bin_proto/impls/
string.rs1#![cfg(feature = "alloc")]
2
3use crate::{util, BitDecode, BitEncode, Error, Result, Untagged};
4
5use alloc::{string::String, vec::Vec};
6use bitstream_io::{BitRead, BitWrite, Endianness};
7
8impl<Tag, Ctx> BitDecode<Ctx, crate::Tag<Tag>> for String
9where
10 Tag: TryInto<usize>,
11{
12 fn decode<R, E>(read: &mut R, ctx: &mut Ctx, tag: crate::Tag<Tag>) -> Result<Self>
13 where
14 R: BitRead,
15 E: Endianness,
16 {
17 let item_count = tag.0.try_into().map_err(|_| Error::TagConvert)?;
18 let mut bytes = Vec::with_capacity(item_count);
19 for _ in 0..item_count {
20 bytes.push(u8::decode::<_, E>(read, ctx, ())?);
21 }
22 Ok(Self::from_utf8(bytes)?)
23 }
24}
25
26impl<Ctx> BitEncode<Ctx, Untagged> for String {
27 fn encode<W, E>(&self, write: &mut W, ctx: &mut Ctx, _: Untagged) -> Result<()>
28 where
29 W: BitWrite,
30 E: Endianness,
31 {
32 util::encode_items::<_, E, _, _>(self.as_bytes(), write, ctx)
33 }
34}
35
36impl<Ctx> BitDecode<Ctx, Untagged> for String {
37 fn decode<R, E>(read: &mut R, ctx: &mut Ctx, _: Untagged) -> Result<Self>
38 where
39 R: BitRead,
40 E: Endianness,
41 {
42 let bytes = util::decode_items_to_eof::<_, E, _, _>(read, ctx).collect::<Result<_>>()?;
43 Ok(Self::from_utf8(bytes)?)
44 }
45}
46
47#[cfg(feature = "prepend-tags")]
48impl<Ctx> BitEncode<Ctx> for String {
49 fn encode<W, E>(&self, write: &mut W, ctx: &mut Ctx, (): ()) -> Result<()>
50 where
51 W: BitWrite,
52 E: Endianness,
53 {
54 self.len().encode::<_, E>(write, ctx, ())?;
55 self.encode::<_, E>(write, ctx, Untagged)
56 }
57}
58
59#[cfg(feature = "prepend-tags")]
60impl<Ctx> BitDecode<Ctx> for String {
61 fn decode<R, E>(read: &mut R, ctx: &mut Ctx, (): ()) -> Result<Self>
62 where
63 R: BitRead,
64 E: Endianness,
65 {
66 let tag = usize::decode::<_, E>(read, ctx, ())?;
67 Self::decode::<_, E>(read, ctx, crate::Tag(tag))
68 }
69}
70
71test_untagged_and_codec!(String| Untagged, crate::Tag(3); "abc".into() => [b'a', b'b', b'c']);
72
73#[cfg(feature = "prepend-tags")]
74test_roundtrip!(String);