1use alloc::borrow::Cow;
12use core::ops::Deref;
13
14use crate::de::{DecodeSlot, FormatDecoder, NsonDeserialize};
15use crate::error::{Error, Result};
16use crate::schema::{NsonSchema, TypeSchema};
17use crate::ser::{FormatEncoder, NsonSerialize};
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
31pub struct Bytes<'a>(pub &'a [u8]);
32
33impl<'a> Bytes<'a> {
34 pub fn as_bytes(&self) -> &'a [u8] {
36 self.0
37 }
38}
39
40impl<'a> From<&'a [u8]> for Bytes<'a> {
41 fn from(bytes: &'a [u8]) -> Self {
42 Bytes(bytes)
43 }
44}
45
46impl<'a> From<&'a str> for Bytes<'a> {
47 fn from(text: &'a str) -> Self {
48 Bytes(text.as_bytes())
49 }
50}
51
52impl<'a> Deref for Bytes<'a> {
53 type Target = [u8];
54 fn deref(&self) -> &[u8] {
55 self.0
56 }
57}
58
59impl<'a> AsRef<[u8]> for Bytes<'a> {
60 fn as_ref(&self) -> &[u8] {
61 self.0
62 }
63}
64
65impl NsonSchema for Bytes<'_> {
66 const SCHEMA: TypeSchema = TypeSchema::Bytes;
67}
68
69impl NsonSerialize for Bytes<'_> {
70 fn nextencode<E: FormatEncoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
71 encoder.write_bytes(self.0)
72 }
73}
74
75impl<'de, 'a> NsonDeserialize<'de> for Bytes<'a>
76where
77 'de: 'a,
78{
79 fn nextdecode_into<D: FormatDecoder<'de>>(
80 decoder: &mut D,
81 out: &mut DecodeSlot<Self>,
82 ) -> Result<(), D::Error> {
83 match decoder.bytes()? {
84 Cow::Borrowed(b) => {
85 out.write(Bytes(b));
86 Ok(())
87 }
88 Cow::Owned(_) => Err(Error::invalid_type(
89 "a borrowed byte string (no escape sequences)",
90 "bytes",
91 )
92 .into()),
93 }
94 }
95}