1use static_assertions::assert_not_impl_all;
2use std::{cell::Cell, ffi::CStr, marker::PhantomData};
3
4use crate::bind;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct SdlVersion {
9 pub major: u8,
11 pub minor: u8,
13 pub patch: u8,
15}
16
17impl From<bind::SDL_version> for SdlVersion {
18 fn from(
19 bind::SDL_version {
20 major,
21 minor,
22 patch,
23 }: bind::SDL_version,
24 ) -> Self {
25 Self {
26 major,
27 minor,
28 patch,
29 }
30 }
31}
32
33pub struct Sdl {
35 _phantom: PhantomData<Cell<u8>>,
36}
37
38assert_not_impl_all!(Sdl: Send, Sync);
39
40impl Sdl {
41 #[must_use]
47 pub fn new() -> Self {
48 let ret = unsafe {
49 bind::SDL_SetMainReady();
50 bind::SDL_Init(0)
51 };
52 if ret != 0 {
53 Self::error_then_panic("Sdl")
54 }
55 Self {
56 _phantom: PhantomData,
57 }
58 }
59
60 #[must_use]
62 pub fn version() -> SdlVersion {
63 use bind::SDL_version;
64 let mut ver = SDL_version {
65 major: 0,
66 minor: 0,
67 patch: 0,
68 };
69 unsafe { bind::SDL_GetVersion(&mut ver) }
70 ver.into()
71 }
72
73 #[must_use]
75 pub fn revision_str() -> &'static str {
76 let raw_str = unsafe { bind::SDL_GetRevision() };
77 unsafe { std::ffi::CStr::from_ptr(raw_str) }
78 .to_str()
79 .expect("Getting revision failed")
80 }
81
82 #[must_use]
84 pub fn revision_num() -> u32 {
85 (unsafe { bind::SDL_GetRevisionNumber() }) as u32
86 }
87
88 #[must_use]
90 pub fn platform() -> &'static str {
91 let cstr = unsafe { CStr::from_ptr(bind::SDL_GetPlatform()) };
92 cstr.to_str().unwrap()
93 }
94
95 #[inline(always)]
97 pub fn error_then_panic(context: &'static str) -> ! {
98 eprintln!("{} error: {}", context, Self::error());
99 panic!("Unrecoverable Sdl error occurred");
100 }
101
102 #[must_use]
104 pub fn error() -> String {
105 let raw_str = unsafe { bind::SDL_GetError() };
106 let error = unsafe { std::ffi::CStr::from_ptr(raw_str) }
107 .to_str()
108 .expect("Getting error failed")
109 .to_owned();
110 unsafe { bind::SDL_ClearError() }
111 error
112 }
113}
114
115impl Default for Sdl {
116 fn default() -> Self {
117 Self::new()
118 }
119}
120
121impl Drop for Sdl {
122 fn drop(&mut self) {
123 unsafe { bind::SDL_Quit() }
124 }
125}