rsomeip_bytes/string.rs
1//! Dynamic and static strings.
2//!
3//! This module provides the [`DynamicString`] and [`StaticString`] types from serializing and
4//! deserializing strings from the SOME/IP on-wire format. It also provides the [`Encoding`] trait
5//! and types for specifying the string encoding.
6
7use crate::{Deserialize, DeserializeError, Serialize, SerializeError};
8use alloc::{string::String, vec::Vec};
9use bytes::{Buf, BufMut};
10use core::marker::PhantomData;
11
12/// Size of the string encoding in bytes.
13///
14/// Includes the size of the Byte Order Mark and the Delimiter.
15///
16/// It's the same for UTF-8 and UTF-16.
17const ENCODING_SIZE: usize = 4;
18
19/// String encoding according to the SOME/IP on-wire format.
20pub trait Encoding: Sealed {
21 /// Serializes the `value` into the given `buffer`.
22 ///
23 /// Includes a Byte Order Mark and a Delimiter before and after the actual string, respectively.
24 ///
25 /// The string must not contain any null characters.
26 ///
27 /// Returns the length of the serialized data.
28 ///
29 /// # Errors
30 ///
31 /// Returns a [`SerializeError`] if the serialization fails. Some data may still be written to
32 /// the buffer if an error occurs.
33 ///
34 /// # Examples
35 ///
36 /// ```rust
37 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
38 /// use rsomeip_bytes::{Encoding as _, Utf8};
39 ///
40 /// // The buffer can be any type that implements `BufMut`.
41 /// let mut buffer = [0_u8; 11];
42 /// let size = Utf8::serialize("rsomeip", &mut buffer.as_mut_slice())?;
43 ///
44 /// // Size includes the size of the Byte Order Mark, string and delimiter.
45 /// assert_eq!(size, 11);
46 /// assert_eq!(buffer.as_slice(), [
47 /// 0xef_u8, 0xbb, 0xbf, // UTF-8 BOM
48 /// 0x72, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x70, // "rsomeip"
49 /// 0x00, // Delimiter
50 /// ].as_slice());
51 /// # Ok(()) }
52 /// ```
53 fn serialize<Value, Buffer>(value: Value, buffer: &mut Buffer) -> Result<usize, SerializeError>
54 where
55 Value: AsRef<str>,
56 Buffer: BufMut + ?Sized;
57
58 /// Returns the size of the `value` when serialized.
59 ///
60 /// Includes the size of the Byte Order Mark and the Delimiter.
61 ///
62 /// Returns [`None`] if the size is out of bounds.
63 ///
64 /// # Examples
65 ///
66 /// ```rust
67 /// use rsomeip_bytes::{Encoding as _, Utf8, Utf16BE, Utf16LE};
68 ///
69 /// // Size includes the size of the Byte Order Mark, string and delimiter.
70 /// assert_eq!(Utf8::size("rsomeip"), Some(11));
71 /// assert_eq!(Utf16BE::size("rsomeip"), Some(18));
72 /// assert_eq!(Utf16LE::size("rsomeip"), Some(18));
73 /// ```
74 fn size<Value>(value: &Value) -> Option<usize>
75 where
76 Value: AsRef<str> + ?Sized;
77
78 /// Deserializes a null-terminated [`String`] from the given `buffer`.
79 ///
80 /// Expects a Byte Order Mark and a Delimiter at the start and end of the string, respectively.
81 ///
82 /// # Errors
83 ///
84 /// Returns a [`DeserializeError`] if the deserialization fails.
85 ///
86 /// Specifically, deserialization fails if the string is not null-terminated or if there is a
87 /// null character before the end of the string.
88 ///
89 /// # Examples
90 ///
91 /// ```rust
92 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
93 /// use rsomeip_bytes::{Encoding as _, Utf8};
94 ///
95 /// // The buffer can be any type that implements `Buf`.
96 /// let buffer = [
97 /// 0xef_u8, 0xbb, 0xbf, // UTF-8 BOM
98 /// 0x72, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x70, // "rsomeip"
99 /// 0x00, // Delimiter
100 /// ];
101 ///
102 /// let string = Utf8::deserialize(&mut buffer.as_slice())?;
103 /// assert_eq!(&string, "rsomeip");
104 /// # Ok(()) }
105 /// ```
106 fn deserialize<Buffer>(buffer: &mut Buffer) -> Result<String, DeserializeError>
107 where
108 Buffer: Buf + ?Sized;
109}
110
111/// Sealed trait to prevent external implementations.
112pub trait Sealed {}
113
114/// UTF-8 encoding for strings.
115///
116/// Normally, used with [`StaticString`] and [`DynamicString`].
117///
118/// # Examples
119///
120/// ```rust
121/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
122/// use rsomeip_bytes::{StaticString, Utf8, Serialize as _, Deserialize as _};
123///
124/// // A `StaticString` can be used to always write the same amount of data regardless
125/// // of the size of the string.
126/// let value = String::from("rsomeip");
127/// let string = StaticString::<11, Utf8, _>::from(&value);
128///
129/// // Buffer can be any type that implements `BufMut`.
130/// let mut buffer = [0_u8; 11];
131///
132/// // Serialized data includes Byte Order Mark and Delimiter.
133/// assert_eq!(Ok(11), string.serialize(&mut buffer.as_mut_slice()));
134/// assert_eq!(buffer, [
135/// 0xef_u8, 0xbb, 0xbf, // UTF-8 BOM
136/// 0x72, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x70, // "rsomeip"
137/// 0x00, // Delimiter
138/// ]);
139///
140/// // Deserialization automatically strips the BOM and Delimiter.
141/// let output = StaticString::<11, Utf8, String>::deserialize(&mut buffer.as_slice())?;
142/// assert_eq!(output, value);
143/// # Ok(()) }
144/// ```
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
146pub struct Utf8;
147
148impl Encoding for Utf8 {
149 fn serialize<Value, Buffer>(value: Value, buffer: &mut Buffer) -> Result<usize, SerializeError>
150 where
151 Value: AsRef<str>,
152 Buffer: BufMut + ?Sized,
153 {
154 let string = value.as_ref();
155
156 // UTF-8 Byte Order Mark + String + Delimiter
157 buffer.put_slice(&[0xef_u8, 0xbb, 0xbf]);
158 buffer.put_slice(string.as_bytes()); // The string is already UTF-8 encoded.
159 buffer.put_u8(0x00);
160
161 // Total size.
162 Self::size(&string).ok_or(SerializeError::SizeOverflow)
163 }
164
165 fn size<Value>(value: &Value) -> Option<usize>
166 where
167 Value: AsRef<str> + ?Sized,
168 {
169 // The string is already UTF-8 encoded.
170 value.as_ref().len().checked_add(ENCODING_SIZE)
171 }
172
173 fn deserialize<Buffer>(buffer: &mut Buffer) -> Result<String, DeserializeError>
174 where
175 Buffer: Buf + ?Sized,
176 {
177 // Extract the Byte Order Mark.
178 if <[u8; 3]>::deserialize(buffer)? != [0xef_u8, 0xbb, 0xbf] {
179 return Err(DeserializeError::invariant("invalid UTF-8 Byte Order Mark"));
180 }
181 // Extract the remainder of the buffer to a vector.
182 let mut raw = Vec::new();
183 raw.put(buffer);
184 // Check if the string is correctly null terminated.
185 let trimmed = remove_delimiters(raw, 0)?;
186 // Convert the vector into an UTF-8 string.
187 String::from_utf8(trimmed)
188 .map_err(|_err| DeserializeError::invariant("invalid UTF-8 string"))
189 }
190}
191
192impl Sealed for Utf8 {}
193
194/// UTF-16 Little Endian encoding for strings.
195///
196/// Normally, used with [`StaticString`] and [`DynamicString`].
197///
198/// # Examples
199///
200/// ```rust
201/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
202/// use rsomeip_bytes::{StaticString, Utf16LE, Serialize as _, Deserialize as _};
203///
204/// // A `StaticString` can be used to always write the same amount of data regardless
205/// // of the size of the string.
206/// let value = String::from("rsomeip");
207/// let string = StaticString::<18, Utf16LE, _>::from(&value);
208///
209/// // Buffer can be any type that implements `BufMut`.
210/// let mut buffer = [0_u8; 18];
211///
212/// // Serialized data includes Byte Order Mark and Delimiter.
213/// assert_eq!(Ok(18), string.serialize(&mut buffer.as_mut_slice()));
214/// assert_eq!(buffer, [
215/// 0xff, 0xfe, // UTF-16LE BOM
216/// 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, 0, // "rsomeip"
217/// 0x00, 0x00 // Delimiter
218/// ]);
219///
220/// // Deserialization automatically strips the BOM and Delimiter.
221/// let output = StaticString::<18, Utf16LE, String>::deserialize(&mut buffer.as_slice())?;
222/// assert_eq!(output, value);
223/// # Ok(()) }
224/// ```
225#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
226pub struct Utf16LE;
227
228impl Encoding for Utf16LE {
229 fn serialize<Value, Buffer>(value: Value, buffer: &mut Buffer) -> Result<usize, SerializeError>
230 where
231 Value: AsRef<str>,
232 Buffer: BufMut + ?Sized,
233 {
234 let string = value.as_ref();
235 let mut size = ENCODING_SIZE; // BOM + Delimiter
236
237 // UTF-16 Byte Order Mark + String + Delimiter
238 buffer.put_u16_le(0xfeff);
239 for charater in string.encode_utf16() {
240 buffer.put_u16_le(charater);
241 // Update the total size of the string.
242 size = size
243 .checked_add(size_of::<u16>())
244 .ok_or(SerializeError::SizeOverflow)?;
245 }
246 buffer.put_u16_le(0x0000);
247
248 // Return the total size.
249 Ok(size)
250 }
251
252 fn size<Value>(value: &Value) -> Option<usize>
253 where
254 Value: AsRef<str> + ?Sized,
255 {
256 value
257 .as_ref()
258 .encode_utf16()
259 .count()
260 .checked_mul(size_of::<u16>())
261 .and_then(|size| size.checked_add(ENCODING_SIZE))
262 }
263
264 fn deserialize<Buffer>(buffer: &mut Buffer) -> Result<String, DeserializeError>
265 where
266 Buffer: Buf + ?Sized,
267 {
268 // Extract the Byte Order Mark.
269 if 0xfffe != u16::deserialize(buffer)? {
270 return Err(DeserializeError::invariant(
271 "invalid UTF-16LE Byte Order Mark",
272 ));
273 }
274 // Extract the remainder of the buffer to a vector.
275 let raw = deserialize_raw_utf16(buffer, |buffer| {
276 buffer
277 .try_get_u16_le()
278 .map_err(|_err| DeserializeError::InsufficientData)
279 })?;
280 // Check if the string is correctly null terminated.
281 let trimmed = remove_delimiters(raw, 0)?;
282 // Convert the vector into an UTF-16 string.
283 String::from_utf16(&trimmed)
284 .map_err(|_err| DeserializeError::invariant("invalid UTF-16LE string"))
285 }
286}
287
288impl Sealed for Utf16LE {}
289
290/// UTF-16 Big Endian encoding for strings.
291///
292/// Normally, used with [`StaticString`] and [`DynamicString`].
293///
294/// # Examples
295///
296/// ```rust
297/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
298/// use rsomeip_bytes::{StaticString, Utf16BE, Serialize as _, Deserialize as _};
299///
300/// // A `StaticString` can be used to always write the same amount of data regardless
301/// // of the size of the string.
302/// let value = String::from("rsomeip");
303/// let string = StaticString::<18, Utf16BE, _>::from(&value);
304///
305/// // Buffer can be any type that implements `BufMut`.
306/// let mut buffer = [0_u8; 18];
307///
308/// // Serialized data includes Byte Order Mark and Delimiter.
309/// assert_eq!(Ok(18), string.serialize(&mut buffer.as_mut_slice()));
310/// assert_eq!(buffer, [
311/// 0xfe, 0xff, // UTF-16BE BOM
312/// 0, 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, // "rsomeip"
313/// 0x00, 0x00 // Delimiter
314/// ]);
315///
316/// // Deserialization automatically strips the BOM and Delimiter.
317/// let output = StaticString::<18, Utf16BE, String>::deserialize(&mut buffer.as_slice())?;
318/// assert_eq!(output, value);
319/// # Ok(()) }
320/// ```
321#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
322pub struct Utf16BE;
323
324impl Encoding for Utf16BE {
325 fn serialize<Value, Buffer>(value: Value, buffer: &mut Buffer) -> Result<usize, SerializeError>
326 where
327 Value: AsRef<str>,
328 Buffer: BufMut + ?Sized,
329 {
330 let string = value.as_ref();
331 let mut size = 4_usize; // BOM + Delimiter
332
333 // UTF-16 Byte Order Mark + String + Delimiter
334 buffer.put_u16(0xfeff);
335 for charater in string.encode_utf16() {
336 buffer.put_u16(charater);
337 // Update the total size of the string.
338 size = size
339 .checked_add(size_of::<u16>())
340 .ok_or(SerializeError::SizeOverflow)?;
341 }
342 buffer.put_u16(0x0000);
343
344 // Return the total size.
345 Ok(size)
346 }
347
348 fn size<Value>(value: &Value) -> Option<usize>
349 where
350 Value: AsRef<str> + ?Sized,
351 {
352 // Same as Little Endian.
353 Utf16LE::size(value)
354 }
355
356 fn deserialize<Buffer>(buffer: &mut Buffer) -> Result<String, DeserializeError>
357 where
358 Buffer: Buf + ?Sized,
359 {
360 // Extract the Byte Order Mark.
361 if 0xfeff != u16::deserialize(buffer)? {
362 return Err(DeserializeError::invariant(
363 "invalid UTF-16BE Byte Order Mark",
364 ));
365 }
366 // Extract the remainder of the buffer to a vector.
367 let raw = deserialize_raw_utf16(buffer, u16::deserialize)?;
368 // Check if the string is correctly null terminated.
369 let trimmed = remove_delimiters(raw, 0)?;
370 // Convert the vector into an UTF-16 string.
371 String::from_utf16(&trimmed)
372 .map_err(|_err| DeserializeError::invariant("invalid UTF-16BE string"))
373 }
374}
375
376impl Sealed for Utf16BE {}
377
378/// Extracts a raw UTF-16 string from the given `buffer`.
379///
380/// Removes odd padding from the end of the string.
381///
382/// # Errors
383///
384/// Returns a [`DeserializeError`] if the deserialization fails or if the odd byte isn't null.
385fn deserialize_raw_utf16<Buffer, Deserializer>(
386 buffer: &mut Buffer,
387 deserialize: Deserializer,
388) -> Result<Vec<u16>, DeserializeError>
389where
390 Buffer: Buf + ?Sized,
391 Deserializer: Fn(&mut Buffer) -> Result<u16, DeserializeError>,
392{
393 let mut raw = Vec::new();
394 loop {
395 match buffer.remaining() {
396 // Nothing to extract.
397 0 => break,
398 // Only one byte remaining.
399 1 => {
400 // Must be padding.
401 if u8::deserialize(buffer)? != 0 {
402 return Err(DeserializeError::invariant("not null terminated"));
403 }
404 }
405 // Two or more bytes remaining. Put them in the Vec.
406 _ => raw.push(deserialize(buffer)?),
407 }
408 }
409 Ok(raw)
410}
411
412/// Extracts the raw string from the given `input` and removes any trailing `delimiter`.
413///
414/// # Errors
415///
416/// Returns a [`DeserializeError::InvariantFailed`] if the string doesn't have a delimiter or if
417/// there is a delimiter in the middle of the string.
418fn remove_delimiters<T>(mut input: Vec<T>, delimiter: T) -> Result<Vec<T>, DeserializeError>
419where
420 T: PartialEq + Copy,
421{
422 input
423 .iter()
424 .position(|&elem| elem == delimiter)
425 .ok_or_else(|| DeserializeError::invariant("not null terminated"))
426 .and_then(|position| {
427 // Trim the delimiter.
428 let remainder = input.split_off(position);
429 // Check for non-null data after the delimiter.
430 if !remainder.is_empty() && remainder.iter().any(|&elem| elem != delimiter) {
431 return Err(DeserializeError::invariant(
432 "null byte before end of string",
433 ));
434 }
435 Ok(input)
436 })
437}
438
439/// Dynamically sized string.
440///
441/// Encodes the size of the string in a preceding length field.
442///
443/// # Examples
444///
445/// ```rust
446/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
447/// use rsomeip_bytes::{DynamicString, LengthU32, Utf8, Serialize as _, Deserialize as _};
448///
449/// // A `DynamicString` encodes the size of the string in a preceeding length field.
450/// let value = String::from("rsomeip");
451/// let string = DynamicString::<LengthU32, Utf8, _>::from(&value);
452///
453/// // Size includes the length field, BOM, string, and delimiter.
454/// assert_eq!(Some(15), string.size());
455/// // Size hint only includes the length field.
456/// assert_eq!(Some(4), DynamicString::<LengthU32, Utf8, String>::size_hint());
457///
458/// // Buffer can be any type that implements `BufMut`.
459/// let mut buffer = [0_u8; 15];
460///
461/// // Serialized data includes Length, Byte Order Mark and Delimiter.
462/// assert_eq!(Ok(15), string.serialize(&mut buffer.as_mut_slice()));
463/// assert_eq!(buffer, [
464/// 0x00_u8, 0x00, 0x00, 0x0b, // Length
465/// 0xef, 0xbb, 0xbf, // UTF-8 BOM
466/// 0x72, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x70, // "rsomeip"
467/// 0x00, // Delimiter
468/// ]);
469///
470/// // Deserialization automatically strips the length, BOM, and delimiters.
471/// let output = DynamicString::<LengthU32, Utf8, String>::deserialize(&mut buffer.as_slice())?;
472/// assert_eq!(output, value);
473/// # Ok(()) }
474/// ```
475pub struct DynamicString<Length, Encoding, Value> {
476 /// String to serialize.
477 inner: Value,
478 /// Length to include before the string.
479 _length: PhantomData<Length>,
480 /// Encoding to use when serializing/deserializing the string.
481 _encoding: PhantomData<Encoding>,
482}
483
484impl<Length, Encoding, Value> From<Value> for DynamicString<Length, Encoding, Value>
485where
486 Length: crate::Length,
487 Encoding: crate::Encoding,
488 Value: AsRef<str>,
489{
490 fn from(value: Value) -> Self {
491 Self {
492 inner: value,
493 _length: PhantomData,
494 _encoding: PhantomData,
495 }
496 }
497}
498
499impl<Length, Encoding, Value> Serialize for DynamicString<Length, Encoding, Value>
500where
501 Length: crate::Length,
502 Encoding: crate::Encoding,
503 Value: AsRef<str>,
504{
505 fn serialize<Buffer>(&self, buffer: &mut Buffer) -> Result<usize, crate::SerializeError>
506 where
507 Buffer: bytes::BufMut + ?Sized,
508 {
509 let wrapper = crate::SerializeWithFn::new(
510 &self.inner,
511 |value: &Value, buf: &mut dyn bytes::BufMut| Encoding::serialize(value, buf),
512 |value: &Value| Encoding::size(value),
513 );
514 Length::serialize(&wrapper, buffer)
515 }
516
517 fn size(&self) -> Option<usize> {
518 Encoding::size(&self.inner).and_then(|size| size.checked_add(Length::size()))
519 }
520}
521
522impl<Length, Encoding, Value> Deserialize for DynamicString<Length, Encoding, Value>
523where
524 Length: crate::Length,
525 Encoding: crate::Encoding,
526 Value: From<String>,
527{
528 type Output = Value;
529
530 fn deserialize<Buffer>(buffer: &mut Buffer) -> Result<Self::Output, crate::DeserializeError>
531 where
532 Buffer: bytes::Buf + ?Sized,
533 {
534 Length::deserialize_with(
535 |buffer| Encoding::deserialize(buffer).map(|value| Value::from(value)),
536 buffer,
537 )
538 }
539
540 fn size_hint() -> Option<usize> {
541 Some(Length::size())
542 }
543}
544
545/// Statically sizes string.
546///
547/// Serialized static strings always have the same length regardless of the size of the actual
548/// string.
549///
550/// Extra space is padded with delimiters.
551///
552/// # Examples
553///
554/// ```rust
555/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
556/// use rsomeip_bytes::{StaticString, Utf8, Serialize as _, Deserialize as _};
557///
558/// // A `StaticString` can be used to always write the same amount of data regardless
559/// // of the size of the string.
560/// let value = String::from("rsomeip");
561/// let string = StaticString::<15, Utf8, _>::from(&value);
562///
563/// // Size is the capacity of the underlying array.
564/// assert_eq!(Some(15), string.size());
565/// assert_eq!(Some(15), StaticString::<15, Utf8, String>::size_hint());
566///
567/// // Buffer can be any type that implements `BufMut`.
568/// let mut buffer = [0_u8; 15];
569///
570/// // Serialized data includes Byte Order Mark, delimiter, and padding.
571/// assert_eq!(Ok(15), string.serialize(&mut buffer.as_mut_slice()));
572/// assert_eq!(buffer, [
573/// 0xef_u8, 0xbb, 0xbf, // UTF-8 BOM
574/// 0x72, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x70, // "rsomeip"
575/// 0x00, // Delimiter
576/// 0x00, 0x00, 0x00, 0x00, // Padding
577/// ]);
578///
579/// // Deserialization automatically strips the BOM, delimiter, and padding.
580/// let output = StaticString::<15, Utf8, String>::deserialize(&mut buffer.as_slice())?;
581/// assert_eq!(output, value);
582/// # Ok(()) }
583/// ```
584pub struct StaticString<const N: usize, Encoding, Value> {
585 /// String to serialize.
586 value: Value,
587 /// Size of the array.
588 _length: PhantomData<[(); N]>,
589 /// Encoding to use when serializing/deserializing the string.
590 _encoding: PhantomData<Encoding>,
591}
592
593impl<Encoding, Value, const N: usize> From<Value> for StaticString<N, Encoding, Value>
594where
595 Encoding: crate::Encoding,
596 Value: AsRef<str>,
597{
598 fn from(value: Value) -> Self {
599 Self {
600 value,
601 _length: PhantomData,
602 _encoding: PhantomData,
603 }
604 }
605}
606
607impl<Encoding, Value, const N: usize> Serialize for StaticString<N, Encoding, Value>
608where
609 Encoding: crate::Encoding,
610 Value: AsRef<str>,
611{
612 fn serialize<Buffer>(&self, buffer: &mut Buffer) -> Result<usize, SerializeError>
613 where
614 Buffer: BufMut + ?Sized,
615 {
616 // Check if the string fits in the array.
617 if Encoding::size(&self.value).ok_or(SerializeError::SizeOverflow)? > N {
618 return Err(SerializeError::invariant(
619 "string exceeds static array capacity",
620 ));
621 }
622 // Limit the amount that can be written into the buffer.
623 let mut limit = buffer.limit(N);
624 // Write the string into the buffer.
625 _ = Encoding::serialize(&self.value, &mut limit)?;
626 // Fill the remaining space with '0'.
627 limit.put_bytes(0, limit.remaining_mut());
628 // Return the size of the array.
629 Ok(N)
630 }
631
632 fn size(&self) -> Option<usize> {
633 Some(N)
634 }
635}
636
637impl<Encoding, Value, const N: usize> Deserialize for StaticString<N, Encoding, Value>
638where
639 Encoding: crate::Encoding,
640 Value: From<String>,
641{
642 type Output = Value;
643
644 fn deserialize<Buffer>(buffer: &mut Buffer) -> Result<Self::Output, DeserializeError>
645 where
646 Buffer: Buf + ?Sized,
647 {
648 Encoding::deserialize(buffer).map(Value::from)
649 }
650
651 fn size_hint() -> Option<usize> {
652 Some(N)
653 }
654}
655
656#[cfg(test)]
657#[expect(clippy::inline_modules, reason = "rust-clippy#17342")]
658mod tests {
659 use super::*;
660 use bytes::BytesMut;
661
662 #[test]
663 fn utf8_delimiter_checks() {
664 let buffer = [
665 0xef_u8, 0xbb, 0xbf, // UTF-8 BOM
666 0x72, 0x73, 0x6f, 0x6d, 0x65, 0x69, 0x70, // "rsomeip"
667 0x00, // Delimiter
668 0x62, 0x79, 0x74, 0x65, 0x73, // "bytes"
669 0x00, // Delimiter
670 ];
671 assert_eq!(
672 <Utf8>::deserialize(&mut buffer.get(0..10).expect("should slice the buffer")),
673 Err(DeserializeError::invariant("not null terminated"))
674 );
675 assert_eq!(
676 <Utf8>::deserialize(&mut buffer.as_slice()),
677 Err(DeserializeError::invariant(
678 "null byte before end of string"
679 ))
680 );
681 }
682
683 #[test]
684 fn utf16be_delimiter_checks() {
685 let buffer = [
686 0xfe_u8, 0xff, // UTF-16 BE BOM
687 0, 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, // "rsomeip"
688 0x00, 0x00, // Delimiter
689 0, 0x62, 0, 0x79, 0, 0x74, 0, 0x65, 0, 0x73, // "bytes"
690 0x00, 0x00, // Delimiter
691 ];
692 assert_eq!(
693 <Utf16BE>::deserialize(&mut buffer.get(0..16).expect("should slice the buffer")),
694 Err(DeserializeError::invariant("not null terminated"))
695 );
696 assert_eq!(
697 <Utf16BE>::deserialize(&mut buffer.as_slice()),
698 Err(DeserializeError::invariant(
699 "null byte before end of string"
700 ))
701 );
702 }
703
704 #[test]
705 fn utf16le_delimiter_checks() {
706 let buffer = [
707 0xff_u8, 0xfe, // UTF-16LE BOM
708 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, 0, // "rsomeip"
709 0x00, 0x00, // Delimiter
710 0x62, 0, 0x79, 0, 0x74, 0, 0x65, 0, 0x73, 0, // "bytes"
711 0x00, 0x00, // Delimiter
712 ];
713 assert_eq!(
714 <Utf16LE>::deserialize(&mut buffer.get(0..16).expect("should slice the buffer")),
715 Err(DeserializeError::invariant("not null terminated"))
716 );
717 assert_eq!(
718 <Utf16LE>::deserialize(&mut buffer.as_slice()),
719 Err(DeserializeError::invariant(
720 "null byte before end of string"
721 ))
722 );
723 }
724
725 #[test]
726 fn utf16be_odd_padding() {
727 let buffer = [
728 0xfe_u8, 0xff, // UTF-16 BE BOM
729 0, 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, // "rsomeip"
730 0x00, 0x00, // Delimiter
731 0x00, // Padding
732 ];
733 assert_eq!(
734 Utf16BE::deserialize(&mut buffer.as_slice()),
735 Ok(String::from("rsomeip"))
736 );
737 }
738
739 #[test]
740 fn utf16le_odd_padding() {
741 let buffer = [
742 0xff_u8, 0xfe, // UTF-16LE BOM
743 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, 0, // "rsomeip"
744 0x00, 0x00, // Delimiter
745 0x00, // Padding
746 ];
747 assert_eq!(
748 Utf16LE::deserialize(&mut buffer.as_slice()),
749 Ok(String::from("rsomeip"))
750 );
751 }
752
753 #[test]
754 fn utf16be_invalid_padding() {
755 let buffer = [
756 0xfe_u8, 0xff, // UTF-16 BE BOM
757 0, 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, // "rsomeip"
758 0x00, 0x00, // Delimiter
759 0x01, // Padding
760 ];
761 assert_eq!(
762 Utf16BE::deserialize(&mut buffer.as_slice()),
763 Err(DeserializeError::invariant("not null terminated"))
764 );
765 }
766
767 #[test]
768 fn utf16le_invalid_padding() {
769 let buffer = [
770 0xff_u8, 0xfe, // UTF-16LE BOM
771 0x72, 0, 0x73, 0, 0x6f, 0, 0x6d, 0, 0x65, 0, 0x69, 0, 0x70, 0, // "rsomeip"
772 0x00, 0x00, // Delimiter
773 0x01, // Padding
774 ];
775 assert_eq!(
776 Utf16LE::deserialize(&mut buffer.as_slice()),
777 Err(DeserializeError::invariant("not null terminated"))
778 );
779 }
780
781 #[test]
782 fn utf8_bom_check() {
783 let buffer = [
784 0xef_u8, 0x00, 0xbf, // Invalid BOM
785 0x00, // Delimiter
786 ];
787 assert_eq!(
788 Utf8::deserialize(&mut buffer.as_slice()),
789 Err(DeserializeError::invariant("invalid UTF-8 Byte Order Mark"))
790 );
791 }
792
793 #[test]
794 fn utf16be_bom_check() {
795 let buffer = [
796 0xff_u8, 0x00, // Invalid BOM
797 0x00, 0x00, // Delimiter
798 ];
799 assert_eq!(
800 Utf16BE::deserialize(&mut buffer.as_slice()),
801 Err(DeserializeError::invariant(
802 "invalid UTF-16BE Byte Order Mark"
803 ))
804 );
805 }
806
807 #[test]
808 fn utf16le_bom_check() {
809 let buffer = [
810 0xfe_u8, 0x00, // Invalid BOM
811 0x00, 0x00, // Delimiter
812 ];
813 assert_eq!(
814 Utf16LE::deserialize(&mut buffer.as_slice()),
815 Err(DeserializeError::invariant(
816 "invalid UTF-16LE Byte Order Mark"
817 ))
818 );
819 }
820
821 #[test]
822 fn utf8_empty_string() {
823 let buffer = [
824 0xef_u8, 0xbb, 0xbf, // UTF-8 BOM
825 0x00, // Delimiter
826 ];
827 assert_eq!(Utf8::deserialize(&mut buffer.as_slice()), Ok(String::new()));
828 }
829
830 #[test]
831 fn utf16be_empty_string() {
832 let buffer = [
833 0xfe_u8, 0xff, // UTF-16 BE BOM
834 0x00, 0x00, // Delimiter
835 ];
836 assert_eq!(
837 Utf16BE::deserialize(&mut buffer.as_slice()),
838 Ok(String::new())
839 );
840 }
841
842 #[test]
843 fn utf16le_empty_string() {
844 let buffer = [
845 0xff_u8, 0xfe, // UTF-16LE BOM
846 0x00, 0x00, // Delimiter
847 ];
848 assert_eq!(
849 Utf16LE::deserialize(&mut buffer.as_slice()),
850 Ok(String::new())
851 );
852 }
853
854 #[test]
855 fn static_string_exceeds_capacity() {
856 assert_eq!(
857 StaticString::<4, Utf8, _>::from("rsomeip").serialize(&mut BytesMut::with_capacity(11)),
858 Err(SerializeError::invariant(
859 "string exceeds static array capacity"
860 ))
861 );
862 }
863}