1use super::*;
7
8
9pub type NonNullFREData = NonNull<c_void>;
10pub type NonNullFREObject = NonNull<c_void>;
11
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14#[repr(transparent)]
15pub struct NonNegativeInt(i32);
16impl NonNegativeInt {
17 pub const MIN: Self = Self(0);
18 pub const MAX: Self = Self(i32::MAX);
19 pub fn new (value: i32) -> Option<Self> {
20 if value >= 0 {
21 Some(Self(value))
22 } else {
23 None
24 }
25 }
26 pub fn get (self) -> i32 {self.0}
27}
28impl Default for NonNegativeInt {
29 fn default() -> Self {Self::MIN}
30}
31
32
33#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct UCStr(UCStrValue);
36#[derive(Debug, Clone, PartialEq, Eq)]
37enum UCStrValue {
38 Static(&'static CStr),
39 Heap(Arc<CStr>),
40}
41impl UCStr {
42 pub const fn from_literal (literal: &'static CStr) -> Result<Self, Utf8Error> {
43 match literal.to_str() {
44 Ok(_) => Ok(Self(UCStrValue::Static(literal))),
45 Err(e) => Err(e),
46 }
47 }
48 pub const unsafe fn from_literal_unchecked (literal: &'static CStr) -> Self {
49 debug_assert!(literal.to_str().is_ok());
50 Self(UCStrValue::Static(literal))
51 }
52 #[inline]
53 pub fn as_str (&self) -> &str {
54 let s = match self.0 {
55 UCStrValue::Static(s) => s.to_bytes(),
56 UCStrValue::Heap(ref s) => s.to_bytes(),
57 };
58 unsafe {str::from_utf8_unchecked(s)}
59 }
60 pub fn as_c_str (&self) -> &CStr {
61 match self.0 {
62 UCStrValue::Static(s) => s,
63 UCStrValue::Heap(ref s) => s.as_ref(),
64 }
65 }
66 pub fn as_ptr (&self) -> FREStr {
68 match self.0 {
69 UCStrValue::Static(s) => s.as_ptr() as FREStr,
70 UCStrValue::Heap(ref s) => s.as_ptr() as FREStr,
71 }
72 }
73 pub fn to_c_string (&self) -> CString {
74 match self.0 {
75 UCStrValue::Static(s) => s.to_owned(),
76 UCStrValue::Heap(ref s) => s.as_ref().to_owned(),
77 }
78 }
79}
80impl From<UCStr> for CString {
81 fn from(value: UCStr) -> Self {value.to_c_string()}
82}
83impl From<UCStr> for String {
84 fn from(value: UCStr) -> Self {value.to_string()}
85}
86impl TryFrom<String> for UCStr {
87 type Error = NulError;
88 fn try_from(value: String) -> Result<Self, NulError> {
89 CString::new(value).map(|s|{
90 let s = s.into();
91 Self(UCStrValue::Heap(s))
92 })
93 }
94}
95impl TryFrom<&str> for UCStr {
96 type Error = NulError;
97 fn try_from(value: &str) -> Result<Self, NulError> {
98 CString::new(value).map(|s|{
99 let s = s.into();
100 Self(UCStrValue::Heap(s))
101 })
102 }
103}
104impl TryFrom<CString> for UCStr {
105 type Error = Utf8Error;
106 fn try_from(value: CString) -> Result<Self, Utf8Error> {
107 value.to_str()?;
108 let s = value.into();
109 Ok(Self(UCStrValue::Heap(s)))
110 }
111}
112impl TryFrom<&CStr> for UCStr {
113 type Error = Utf8Error;
114 fn try_from(value: &CStr) -> Result<Self, Utf8Error> {
115 value.to_str().map(|_|{
116 let s = value.to_owned().into();
117 Self(UCStrValue::Heap(s))
118 })
119 }
120}
121impl PartialEq<str> for UCStr {
122 #[inline]
123 fn eq(&self, other: &str) -> bool { self.as_str() == other }
124}
125impl PartialEq<UCStr> for str {
126 #[inline]
127 fn eq(&self, other: &UCStr) -> bool { self == other.as_str() }
128}
129impl PartialOrd for UCStr {
130 #[inline]
131 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { self.as_str().partial_cmp(other.as_str()) }
132}
133impl Ord for UCStr {
134 #[inline]
135 fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.as_str().cmp(other.as_str()) }
136}
137impl std::hash::Hash for UCStr {
138 #[inline]
139 fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.as_str().hash(state) }
140}
141impl AsRef<str> for UCStr {
142 fn as_ref(&self) -> &str { self.as_str() }
143}
144impl AsRef<CStr> for UCStr {
145 fn as_ref(&self) -> &CStr { self.as_c_str() }
146}
147impl std::borrow::Borrow<str> for UCStr {
148 #[inline]
149 fn borrow(&self) -> &str { self.as_str() }
150}
151impl Display for UCStr {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Display::fmt(self.as_str(), f) }
153}