ros2_client/
wide_string.rs

1// Wide string, i.e. UTF-16 Strings
2// We just wrap a pre-existing library to get proper Serialize and Deserialize.
3
4use std::fmt;
5
6use serde::{
7  de::{SeqAccess, Visitor},
8  ser::SerializeSeq,
9  Deserialize, Deserializer, Serialize, Serializer,
10};
11use widestring::Utf16String;
12
13/// UTF-16 strings, as required by the ROS type system.
14///
15/// We just wrap a pre-existing library to get proper Serialize and Deserialize.
16#[derive(Clone, Debug)]
17pub struct WString {
18  inner: Utf16String,
19}
20
21impl WString {
22  pub fn new() -> Self {
23    WString {
24      inner: Utf16String::new(),
25    }
26  }
27}
28
29impl Default for WString {
30  fn default() -> Self {
31    Self::new()
32  }
33}
34
35impl From<Utf16String> for WString {
36  fn from(inner: Utf16String) -> Self {
37    WString { inner }
38  }
39}
40
41impl From<WString> for Utf16String {
42  fn from(w: WString) -> Utf16String {
43    w.inner
44  }
45}
46
47impl core::ops::Deref for WString {
48  type Target = Utf16String;
49  fn deref(&self) -> &Self::Target {
50    &self.inner
51  }
52}
53
54impl Serialize for WString {
55  fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
56    let mut seq = serializer.serialize_seq(Some(self.inner.len()))?;
57    for e in self.inner.as_slice() {
58      seq.serialize_element(e)?;
59    }
60    seq.end()
61  }
62}
63
64impl<'de> Deserialize<'de> for WString {
65  fn deserialize<D>(deserializer: D) -> Result<WString, D::Error>
66  where
67    D: Deserializer<'de>,
68  {
69    deserializer.deserialize_seq(WStringVisitor)
70  }
71}
72
73struct WStringVisitor;
74
75impl<'de> Visitor<'de> for WStringVisitor {
76  type Value = WString;
77
78  fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
79    write!(formatter, "a wide string in UTF-16")
80  }
81
82  fn visit_seq<A>(self, mut seq: A) -> Result<WString, A::Error>
83  where
84    A: SeqAccess<'de>,
85  {
86    let mut inner: Utf16String = seq
87      .size_hint()
88      .map_or_else(Utf16String::new, Utf16String::with_capacity);
89    while let Some(wc) = seq.next_element()? {
90      inner.push(wc)
91    }
92    Ok(inner.into())
93  }
94}