1#![no_std]
18
19#[cfg(feature = "alloc")]
23extern crate alloc;
24#[cfg(feature = "arrayvec")]
25extern crate arrayvec;
26#[cfg(feature = "smallvec")]
27extern crate smallvec;
28
29pub trait Write16 {
31 fn write_slice(&mut self, s: &[u16]) -> core::fmt::Result;
37
38 #[inline(always)]
40 fn write_char(&mut self, c: char) -> core::fmt::Result {
41 let mut buf = [0u16; 2];
42 self.write_slice(c.encode_utf16(&mut buf))
43 }
44
45 #[inline(always)]
55 fn size_hint(&mut self, upcoming: usize) -> core::fmt::Result {
56 let _ = upcoming;
57 Ok(())
58 }
59}
60
61#[cfg(feature = "alloc")]
62impl Write16 for alloc::vec::Vec<u16> {
63 #[inline(always)]
64 fn write_slice(&mut self, s: &[u16]) -> core::fmt::Result {
65 self.extend_from_slice(s);
66 Ok(())
67 }
68
69 #[inline(always)]
70 fn write_char(&mut self, c: char) -> core::fmt::Result {
71 if c <= '\u{FFFF}' {
72 self.push(c as u16);
73 } else {
74 let mut buf = [0u16; 2];
75 let u = u32::from(c);
76 buf[0] = (0xD7C0 + (u >> 10)) as u16;
77 buf[1] = (0xDC00 + (u & 0x3FF)) as u16;
78 self.extend_from_slice(&mut buf);
79 }
80 Ok(())
81 }
82
83 #[inline(always)]
84 fn size_hint(&mut self, upcoming: usize) -> core::fmt::Result {
85 self.reserve(upcoming);
86 Ok(())
87 }
88}
89
90#[cfg(feature = "smallvec")]
91impl<A: smallvec::Array<Item = u16>> Write16 for smallvec::SmallVec<A> {
92 #[inline(always)]
93 fn write_slice(&mut self, s: &[u16]) -> core::fmt::Result {
94 self.extend_from_slice(s);
95 Ok(())
96 }
97
98 #[inline(always)]
99 fn write_char(&mut self, c: char) -> core::fmt::Result {
100 if c <= '\u{FFFF}' {
101 self.push(c as u16);
102 } else {
103 let mut buf = [0u16; 2];
104 let u = u32::from(c);
105 buf[0] = (0xD7C0 + (u >> 10)) as u16;
106 buf[1] = (0xDC00 + (u & 0x3FF)) as u16;
107 self.extend_from_slice(&mut buf);
108 }
109 Ok(())
110 }
111
112 #[inline(always)]
113 fn size_hint(&mut self, upcoming: usize) -> core::fmt::Result {
114 self.reserve(upcoming);
115 Ok(())
116 }
117}
118
119#[cfg(feature = "arrayvec")]
120impl<const CAP: usize> Write16 for arrayvec::ArrayVec<u16, CAP> {
121 #[inline(always)]
122 fn write_slice(&mut self, s: &[u16]) -> core::fmt::Result {
123 if self.try_extend_from_slice(s).is_ok() {
124 Ok(())
125 } else {
126 Err(core::fmt::Error {})
127 }
128 }
129
130 #[inline(always)]
131 fn write_char(&mut self, c: char) -> core::fmt::Result {
132 if c <= '\u{FFFF}' {
133 if self.try_push(c as u16).is_ok() {
134 Ok(())
135 } else {
136 Err(core::fmt::Error {})
137 }
138 } else {
139 let mut buf = [0u16; 2];
140 let u = u32::from(c);
141 buf[0] = (0xD7C0 + (u >> 10)) as u16;
142 buf[1] = (0xDC00 + (u & 0x3FF)) as u16;
143 self.write_slice(&mut buf)
144 }
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use crate::Write16;
151
152 #[cfg(feature = "alloc")]
153 #[test]
154 fn test_vec() {
155 let mut v: alloc::vec::Vec<u16> = alloc::vec::Vec::new();
156 assert_eq!(v.capacity(), 0);
157 assert!(v.size_hint(32).is_ok());
158 assert!(v.capacity() >= 32);
159 assert_eq!(v.len(), 0);
160 assert!(v.write_slice([0x0061u16, 0x0062u16].as_slice()).is_ok());
161 assert_eq!(v.len(), 2);
162 assert!(v.write_char('☃').is_ok());
163 assert_eq!(v.len(), 3);
164 assert!(v.write_char('😊').is_ok());
165 assert_eq!(v.len(), 5);
166 assert_eq!(
167 v.as_slice(),
168 [0x0061u16, 0x0062u16, 0x2603u16, 0xD83Du16, 0xDE0Au16].as_slice()
169 );
170 }
171
172 #[cfg(feature = "smallvec")]
173 #[test]
174 fn test_smallvec() {
175 let mut v: smallvec::SmallVec<[u16; 2]> = smallvec::SmallVec::new();
176 assert_eq!(v.capacity(), 2);
177 assert!(v.size_hint(32).is_ok());
178 assert!(v.capacity() >= 32);
179 assert_eq!(v.len(), 0);
180 assert!(v.write_slice([0x0061u16, 0x0062u16].as_slice()).is_ok());
181 assert_eq!(v.len(), 2);
182 assert!(v.write_char('☃').is_ok());
183 assert_eq!(v.len(), 3);
184 assert!(v.write_char('😊').is_ok());
185 assert_eq!(v.len(), 5);
186 assert_eq!(
187 v.as_slice(),
188 [0x0061u16, 0x0062u16, 0x2603u16, 0xD83Du16, 0xDE0Au16].as_slice()
189 );
190 }
191
192 #[cfg(feature = "arrayvec")]
193 #[test]
194 fn test_arrayvec() {
195 let mut v: arrayvec::ArrayVec<u16, 4> = arrayvec::ArrayVec::new();
196 assert_eq!(v.capacity(), 4);
197 assert!(v.size_hint(32).is_ok());
198 assert_eq!(v.capacity(), 4);
199 assert_eq!(v.len(), 0);
200 assert!(v.write_char('😊').is_ok());
201 assert_eq!(v.len(), 2);
202 assert!(v.write_char('☃').is_ok());
203 assert_eq!(v.len(), 3);
204 assert!(v.write_char('😊').is_err());
205 assert_eq!(v.len(), 3);
206 assert_eq!(v.as_slice(), [0xD83Du16, 0xDE0Au16, 0x2603u16].as_slice());
207 }
208}