1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::ffi::OsString;

use crate::{TBuffer, TBytes};

// TODO: Should fix on linux utf16 characters will be ignored
impl TBytes for std::ffi::OsString {
    fn size(&self) -> usize {
        self.len() * 2 + 0usize.size()
    }

    fn to_bytes(&self) -> Vec<u8> {
        let mut buffer = Vec::with_capacity(self.size());
        buffer.append(&mut self.len().to_bytes());
        #[cfg(target_os = "linux")]
        use std::os::unix::ffi::OsStrExt;
        #[cfg(target_os = "windows")]
        use std::os::windows::ffi::OsStrExt;

        #[cfg(target_os = "linux")]
        for byte in self.as_bytes() {
            {
                buffer.push(*byte);
                buffer.push(0);
            }
        }
        #[cfg(target_os = "windows")]
        for byte in self.encode_wide() {
            buffer.append(&mut byte.to_bytes())
        }

        buffer
    }

    fn from_bytes(buffer: &mut TBuffer) -> Option<Self>
    where
        Self: Sized,
    {
        let len = usize::from_bytes(buffer)?;
        let mut buff = Vec::with_capacity(len);
        for _ in 0..len {
            #[cfg(target_os = "linux")]
            {
                buff.push(buffer.next()?);
                buffer.next();
            }
            #[cfg(target_os = "windows")]
            buff.push(u16::from_bytes(buffer)?);
        }
        #[cfg(target_os = "linux")]
        use std::os::unix::ffi::OsStringExt;
        #[cfg(target_os = "windows")]
        use std::os::windows::ffi::OsStringExt;

        #[cfg(target_os = "linux")]
        return Some(OsString::from_vec(buff));
        #[cfg(target_os = "windows")]
        return Some(OsString::from_wide(&buff));
    }
}

#[cfg(test)]
mod test {
    use std::ffi::OsString;

    use crate::TBytes;
    #[test]
    fn os_string() {
        let a = OsString::from("Hello World");
        let mut bytes = a.to_bytes();

        let b = OsString::from_bytes(&mut bytes.drain(..)).unwrap();
        assert_eq!(a, b);
    }
}