rich_sdl2_rust/
hint.rs

1//! Getting/setting hints for SDL2 features working.
2
3use std::{
4    ffi::{CStr, CString},
5    os::raw::c_uint,
6};
7
8use crate::{bind, EnumInt, Result, SdlError};
9
10mod observer;
11
12pub use observer::*;
13
14/// Returns the hint value of the key if exists.
15#[must_use]
16pub fn get_hint(key: &str) -> Option<String> {
17    let cstr = CString::new(key).expect("key must not be empty");
18    let hint = unsafe { bind::SDL_GetHint(cstr.as_ptr()) };
19    (!hint.is_null()).then(|| {
20        unsafe { CStr::from_ptr(hint) }
21            .to_string_lossy()
22            .to_string()
23    })
24}
25
26/// Returns the boolean hint value of the key if exists.
27#[must_use]
28pub fn get_hint_bool(key: &str) -> Option<bool> {
29    let cstr = CString::new(key).expect("key must not be empty");
30    let ret = unsafe { bind::SDL_GetHintBoolean(cstr.as_ptr(), 2) };
31    (ret != 2).then(|| ret == bind::SDL_TRUE)
32}
33
34/// Sets the hint value of the key, or `Err` if does not exist.
35///
36/// # Panics
37///
38/// Panics if `key` or `value` was empty.
39///
40/// # Errors
41///
42/// Returns `Err` if the hint of `key` is unsupported.
43pub fn set_hint(key: &str, value: &str) -> Result<()> {
44    let key_cstr = CString::new(key).expect("key must not be empty");
45    let value_cstr = CString::new(value).expect("value must not be empty");
46    let ret = unsafe { bind::SDL_SetHint(key_cstr.as_ptr(), value_cstr.as_ptr()) };
47    if ret == bind::SDL_TRUE {
48        Ok(())
49    } else {
50        Err(SdlError::UnsupportedFeature)
51    }
52}
53
54/// A priority of the hint specifying.
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56#[non_exhaustive]
57pub enum HintPriority {
58    /// A default priority, low.
59    Default,
60    /// A medium priority.
61    Normal,
62    /// A higher priority.
63    Override,
64}
65
66impl HintPriority {
67    fn into_raw(self) -> EnumInt {
68        match self {
69            HintPriority::Default => 0,
70            HintPriority::Normal => 1,
71            HintPriority::Override => 2,
72        }
73    }
74}
75
76impl Default for HintPriority {
77    fn default() -> Self {
78        Self::Default
79    }
80}
81
82/// Sets a hint value of the key with a priority.
83///
84/// # Errors
85///
86/// Returns `Err` if the hint of `key` does not exist.
87pub fn set_hint_with_priority(key: &str, value: &str, priority: HintPriority) -> Result<()> {
88    let key_cstr = CString::new(key).expect("key must not be empty");
89    let value_cstr = CString::new(value).expect("value must not be empty");
90    let ret = unsafe {
91        bind::SDL_SetHintWithPriority(key_cstr.as_ptr(), value_cstr.as_ptr(), priority.into_raw())
92    };
93    if ret == bind::SDL_TRUE {
94        Ok(())
95    } else {
96        Err(SdlError::UnsupportedFeature)
97    }
98}
99
100/// Clears all the set hints.
101pub fn clear_hints() {
102    unsafe { bind::SDL_ClearHints() }
103}