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 pub fn new<T: Into<Bytes<'a>>>(v: T) -> Self {
22 v.into()
23 }
24
25 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 pub fn to_mut(&mut self) -> &mut Vec<u8> {
39 self.0.to_mut()
40 }
41
42 pub fn as_cow(&self) -> &Cow<'a, [u8]> {
44 &self.0
45 }
46
47 pub fn into_inner(self) -> Cow<'a, [u8]> {
49 self.0
50 }
51
52 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 pub fn new<T: Into<BytesConst<'a, SIZE>>>(v: T) -> Self {
118 v.into()
119 }
120
121 pub fn to_mut(&mut self) -> &mut [u8; SIZE] {
123 self.0.to_mut()
124 }
125
126 pub fn into_inner(self) -> Cow<'a, [u8; SIZE]> {
128 self.0
129 }
130
131 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}