midix/byte/
mod.rs

1mod message;
2use std::{
3    borrow::Cow,
4    io::{self, ErrorKind},
5    ops::Deref,
6};
7
8pub use message::*;
9
10#[doc = r#"
11Wraps a `Cow<'_, u8>`.
12
13This is because Cow doesn't implement From<Vec<u8>> or From<&[u8]>, and a common interface is nice to have
14for [`MidiSource`].
15"#]
16#[derive(Clone, PartialEq, Eq, Debug, Hash)]
17pub struct Bytes<'a>(Cow<'a, [u8]>);
18
19impl<'a> Bytes<'a> {
20    /// Create a new set of bytes
21    pub fn new<T: Into<Bytes<'a>>>(v: T) -> Self {
22        v.into()
23    }
24
25    /// Removes X elements from the end
26    pub fn truncate(&mut self, amt: usize) {
27        match &mut self.0 {
28            Cow::Borrowed(val) => {
29                *val = &val[..val.len() - amt];
30            }
31            Cow::Owned(val) => {
32                val.truncate(amt);
33            }
34        }
35    }
36
37    /// Returns mutable reference to underlying byte slice
38    pub fn to_mut(&mut self) -> &mut Vec<u8> {
39        self.0.to_mut()
40    }
41
42    /// Return a reference to the underlying Cow
43    pub fn as_cow(&self) -> &Cow<'a, [u8]> {
44        &self.0
45    }
46
47    /// Returns the underlying Cow
48    pub fn into_inner(self) -> Cow<'a, [u8]> {
49        self.0
50    }
51
52    /// Returns the underlying byte vec. Copies if borrowed.
53    pub fn into_owned(self) -> Vec<u8> {
54        self.0.into_owned()
55    }
56}
57
58impl<'a> Deref for Bytes<'a> {
59    type Target = <Cow<'a, [u8]> as Deref>::Target;
60    fn deref(&self) -> &Self::Target {
61        &self.0
62    }
63}
64
65impl From<Vec<u8>> for Bytes<'_> {
66    fn from(value: Vec<u8>) -> Self {
67        Self(Cow::Owned(value))
68    }
69}
70
71impl<'a> From<&'a [u8]> for Bytes<'a> {
72    fn from(value: &'a [u8]) -> Self {
73        Self(Cow::Borrowed(value))
74    }
75}
76
77impl<'a, const SIZE: usize> From<&'a [u8; SIZE]> for Bytes<'a> {
78    fn from(value: &'a [u8; SIZE]) -> Self {
79        Self(Cow::Borrowed(value))
80    }
81}
82
83impl<const SIZE: usize> From<[u8; SIZE]> for Bytes<'_> {
84    fn from(value: [u8; SIZE]) -> Self {
85        Self(Cow::Owned(value.to_vec()))
86    }
87}
88
89impl<'a> TryFrom<Bytes<'a>> for Cow<'a, str> {
90    type Error = io::Error;
91    fn try_from(value: Bytes<'a>) -> Result<Self, Self::Error> {
92        match value.0 {
93            Cow::Borrowed(value) => {
94                let text = std::str::from_utf8(value).map_err(|e| {
95                    io::Error::new(ErrorKind::InvalidData, format!("Invalid string: {:?}", e))
96                })?;
97                Ok(Cow::Borrowed(text))
98            }
99            Cow::Owned(v) => {
100                let text = String::from_utf8(v).map_err(|e| {
101                    io::Error::new(ErrorKind::InvalidData, format!("Invalid string: {:?}", e))
102                })?;
103                Ok(Cow::Owned(text))
104            }
105        }
106    }
107}
108
109#[doc = r#"
110A representation of a statically borrowed or owned array
111"#]
112#[derive(Clone, PartialEq, Eq, Debug, Hash)]
113pub struct BytesConst<'a, const SIZE: usize>(Cow<'a, [u8; SIZE]>);
114
115impl<'a, const SIZE: usize> BytesConst<'a, SIZE> {
116    /// Create a new set of bytes
117    pub fn new<T: Into<BytesConst<'a, SIZE>>>(v: T) -> Self {
118        v.into()
119    }
120
121    /// Returns mutable reference to underlying byte slice
122    pub fn to_mut(&mut self) -> &mut [u8; SIZE] {
123        self.0.to_mut()
124    }
125
126    /// Returns the underlying Cow
127    pub fn into_inner(self) -> Cow<'a, [u8; SIZE]> {
128        self.0
129    }
130
131    /// Returns the underlying byte vec. Copies if borrowed.
132    pub fn into_owned(self) -> [u8; SIZE] {
133        self.0.into_owned()
134    }
135}
136impl<'a, const SIZE: usize> Deref for BytesConst<'a, SIZE> {
137    type Target = <Cow<'a, [u8; SIZE]> as Deref>::Target;
138    fn deref(&self) -> &Self::Target {
139        &self.0
140    }
141}
142
143impl<'a, const SIZE: usize> TryFrom<Bytes<'a>> for BytesConst<'a, SIZE> {
144    type Error = ();
145    fn try_from(value: Bytes<'a>) -> Result<Self, Self::Error> {
146        Ok(match value.into_inner() {
147            Cow::Borrowed(v) => Self(Cow::Borrowed(v.try_into().map_err(|_| ())?)),
148            Cow::Owned(v) => Self(Cow::Owned(v.try_into().map_err(|_| ())?)),
149        })
150    }
151}
152
153impl<const SIZE: usize> From<[u8; SIZE]> for BytesConst<'_, SIZE> {
154    fn from(value: [u8; SIZE]) -> Self {
155        Self(Cow::Owned(value))
156    }
157}
158
159impl<'a, const SIZE: usize> From<&'a [u8; SIZE]> for BytesConst<'a, SIZE> {
160    fn from(value: &'a [u8; SIZE]) -> Self {
161        Self(Cow::Borrowed(value))
162    }
163}