Skip to main content

rusteal_core/
fname.rs

1use std::fmt;
2
3use rusteal_ffi::FNameHandle;
4
5use crate::error::check_ffi;
6use crate::ffi_dispatch;
7
8#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
9pub struct FName(pub FNameHandle);
10
11impl FName {
12    pub const NONE: FName = FName(FNameHandle(0));
13
14    pub fn new(name: &str) -> Self {
15        let handle = unsafe { ffi_dispatch::core_make_fname(name.as_ptr(), name.len() as u32) };
16
17        FName(handle)
18    }
19
20    #[inline]
21    pub fn handle(&self) -> FNameHandle {
22        self.0
23    }
24
25    #[inline]
26    pub fn is_none(&self) -> bool {
27        self.0.0 == 0
28    }
29
30    pub fn to_string_lossy(&self) -> String {
31        let mut buf = [0u8; 256];
32        let mut out_len: u32 = 0;
33
34        let code = unsafe {
35            ffi_dispatch::core_fname_to_string(
36                self.0,
37                buf.as_mut_ptr(),
38                buf.len() as u32,
39                &mut out_len,
40            )
41        };
42
43        if check_ffi(code).is_err() {
44            return String::from("<invalid FName>");
45        }
46
47        std::str::from_utf8(&buf[..out_len as usize])
48            .map(|s| s.to_owned())
49            .unwrap_or_else(|_| String::from("<invalid UTF-8>"))
50    }
51}
52
53impl Default for FName {
54    fn default() -> Self {
55        FName::NONE
56    }
57}
58
59impl fmt::Display for FName {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(f, "{}", self.to_string_lossy())
62    }
63}
64
65impl PartialEq<&str> for FName {
66    fn eq(&self, other: &&str) -> bool {
67        self.to_string_lossy() == *other
68    }
69}
70
71impl From<&str> for FName {
72    fn from(s: &str) -> Self {
73        FName::new(s)
74    }
75}
76
77impl From<FName> for FNameHandle {
78    fn from(name: FName) -> FNameHandle {
79        name.0
80    }
81}
82
83impl From<FNameHandle> for FName {
84    fn from(handle: FNameHandle) -> FName {
85        FName(handle)
86    }
87}