rich_sdl2_rust/event/joystick/
guid.rs1use std::{
4 ffi::{CStr, CString},
5 os::raw::c_int,
6};
7
8use crate::bind;
9
10#[derive(Debug, Clone)]
12pub struct Guid([u8; 16]);
13
14impl Guid {
15 #[must_use]
17 pub fn mapping(&self) -> String {
18 let ptr = unsafe {
19 bind::SDL_GameControllerMappingForGUID(bind::SDL_JoystickGUID { data: self.0 })
20 };
21 let cstr = unsafe { CStr::from_ptr(ptr) };
22 let ret = cstr.to_string_lossy().to_string();
23 unsafe { bind::SDL_free(ptr.cast()) };
24 ret
25 }
26}
27
28impl std::fmt::Display for Guid {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 let mut buf = [0u8; 33];
31 unsafe {
32 bind::SDL_JoystickGetGUIDString(
33 bind::SDL_JoystickGUID { data: self.0 },
34 buf.as_mut_ptr().cast(),
35 buf.len() as c_int,
36 );
37 }
38 write!(f, "{}", String::from_utf8_lossy(&buf))
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
44pub struct InvalidLengthError {
45 actual_length: usize,
46}
47
48impl std::fmt::Display for InvalidLengthError {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(
51 f,
52 "length must equals to 16 but actual length was {}",
53 self.actual_length
54 )
55 }
56}
57
58impl std::error::Error for InvalidLengthError {}
59
60impl std::str::FromStr for Guid {
61 type Err = InvalidLengthError;
62
63 fn from_str(s: &str) -> Result<Self, Self::Err> {
64 if s.len() != 16 {
65 return Err(InvalidLengthError {
66 actual_length: s.len(),
67 });
68 }
69 let c_str = CString::new(s).expect("invalid string");
70 let raw_guid = unsafe { bind::SDL_JoystickGetGUIDFromString(c_str.as_ptr()) };
71 Ok(raw_guid.into())
72 }
73}
74
75impl From<bind::SDL_JoystickGUID> for Guid {
76 fn from(raw: bind::SDL_JoystickGUID) -> Self {
77 Self(raw.data)
78 }
79}