1#![deny(missing_docs)]
3
4#[cfg(feature="use_serde")]
5#[macro_use]
6extern crate serde_derive;
7#[cfg(feature="use_serde")]
8extern crate serde;
9
10use std::borrow;
11use std::fmt;
12use std::io::Write;
13use std::mem::transmute;
14use std::ops;
15use std::ptr;
16use std::str;
17use std::cmp;
18use std::hash;
19
20#[cfg(feature="use_serde")]
21use serde::de::Error;
22
23#[derive(Copy, Default)]
27pub struct StringWrapper<T>
28 where T: Buffer
29{
30 len: usize,
31 buffer: T,
32}
33
34pub unsafe trait Buffer {
37 fn as_ref(&self) -> &[u8];
39 fn as_mut(&mut self) -> &mut [u8];
41}
42
43pub trait OwnedBuffer: Buffer {
51 fn new() -> Self;
53}
54
55impl<T> StringWrapper<T>
56 where T: Buffer
57{
58 pub fn new(buffer: T) -> Self {
60 StringWrapper {
61 len: 0,
62 buffer: buffer,
63 }
64 }
65
66 pub unsafe fn from_raw_parts(buffer: T, len: usize) -> Self {
73 StringWrapper {
74 len: len,
75 buffer: buffer,
76 }
77 }
78
79 pub fn into_buffer(self) -> T {
81 self.buffer
82 }
83
84 pub fn buffer(&self) -> &[u8] {
86 self.buffer.as_ref()
87 }
88
89
90 pub unsafe fn buffer_mut(&mut self) -> &mut [u8] {
94 self.buffer.as_mut()
95 }
96
97 pub fn len(&self) -> usize {
99 self.len
100 }
101
102 pub fn is_empty(&self) -> bool {
104 self.len == 0
105 }
106
107 pub unsafe fn set_len(&mut self, new_len: usize) {
111 self.len = new_len
112 }
113
114 pub fn truncate(&mut self, new_len: usize) {
118 assert!(new_len <= self.len);
119 if new_len < self.len {
120 assert!(starts_well_formed_utf8_sequence(self.buffer.as_ref()[new_len]));
121 }
122 self.len = new_len;
123 }
124
125 pub fn capacity(&self) -> usize {
127 self.buffer.as_ref().len()
128 }
129
130 pub fn extra_capacity(&self) -> usize {
132 self.capacity() - self.len
133 }
134
135 pub fn extra_bytes_mut(&mut self) -> &mut [u8] {
137 &mut self.buffer.as_mut()[self.len..]
138 }
139
140 pub fn push(&mut self, c: char) -> Result<(), ()> {
144 let new_len = self.len + c.len_utf8();
145 if new_len <= self.capacity() {
146 write!(self.extra_bytes_mut(), "{}", c).unwrap();
148 self.len = new_len;
149 Ok(())
150 } else {
151 Err(())
152 }
153 }
154
155 pub fn push_str(&mut self, s: &str) {
159 copy_memory(s.as_bytes(), self.extra_bytes_mut());
160 self.len += s.len();
161 }
162
163 pub fn push_partial_str(&mut self, s: &str) -> Result<(), usize> {
169 let mut i = self.extra_capacity();
170 let (s, result) = if i < s.len() {
171 while !starts_well_formed_utf8_sequence(s.as_bytes()[i]) {
174 i -= 1
175 }
176 (&s[..i], Err(i))
177 } else {
178 (s, Ok(()))
179 };
180 self.push_str(s);
181 result
182 }
183}
184
185impl<T: OwnedBuffer> StringWrapper<T> {
186 pub fn from_str(s: &str) -> StringWrapper<T> {
202 let buffer = T::new();
203 let mut sw = StringWrapper::new(buffer);
204 sw.push_str(s);
205 sw
206 }
207
208 pub fn from_str_safe(s: &str) -> Option<StringWrapper<T>> {
227 let buffer = T::new();
228 let mut sw = StringWrapper::new(buffer);
229 match sw.push_partial_str(s) {
230 Ok(_) => Some(sw),
231 Err(_) => None,
232 }
233 }
234}
235
236fn starts_well_formed_utf8_sequence(byte: u8) -> bool {
237 byte < 128 || byte >= 192
239}
240
241fn copy_memory(src: &[u8], dst: &mut [u8]) {
246 let len_src = src.len();
247 assert!(dst.len() >= len_src);
248 unsafe {
251 ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), len_src);
252 }
253}
254
255impl<T> ops::Deref for StringWrapper<T>
256 where T: Buffer
257{
258 type Target = str;
259
260 fn deref(&self) -> &str {
261 unsafe { str::from_utf8_unchecked(&self.buffer.as_ref()[..self.len]) }
262 }
263}
264
265impl<T> ops::DerefMut for StringWrapper<T>
266 where T: Buffer
267{
268 fn deref_mut(&mut self) -> &mut str {
269 unsafe { transmute::<&mut [u8], &mut str>(&mut self.buffer.as_mut()[..self.len]) }
270 }
271}
272
273impl<T> borrow::Borrow<str> for StringWrapper<T>
274 where T: Buffer
275{
276 fn borrow(&self) -> &str {
277 self
278 }
279}
280
281impl<T> fmt::Display for StringWrapper<T>
282 where T: Buffer
283{
284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285 fmt::Display::fmt(&**self, f)
286 }
287}
288
289impl<T> fmt::Debug for StringWrapper<T>
290 where T: Buffer
291{
292 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
293 fmt::Debug::fmt(&**self, f)
294 }
295}
296
297impl<T: Buffer> PartialEq for StringWrapper<T> {
298 fn eq(&self, other: &Self) -> bool {
299 **self == **other
300 }
301}
302
303impl<T: Buffer> Eq for StringWrapper<T> {}
305
306impl<T: Buffer + Copy> Clone for StringWrapper<T> {
310 fn clone(&self) -> Self {
311 *self
312
313 }
314}
315
316impl<T: Buffer> PartialOrd for StringWrapper<T> {
317 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
318 Some(self.cmp(other))
319 }
320}
321
322impl<T: Buffer> hash::Hash for StringWrapper<T> {
323 fn hash<H: hash::Hasher>(&self, state: &mut H) {
324 (**self).hash(state)
325 }
326}
327
328impl<T: Buffer> Ord for StringWrapper<T> {
329 fn cmp(&self, other: &Self) -> cmp::Ordering {
330 (**self).cmp(&**other)
331 }
332}
333
334#[cfg(feature="use_serde")]
335impl<T: Buffer> serde::Serialize for StringWrapper<T> {
336 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
337 self.to_string().serialize(serializer)
338 }
339}
340
341#[cfg(feature="use_serde")]
342impl<'de, T: OwnedBuffer> serde::Deserialize<'de> for StringWrapper<T> {
343 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
344 let s: String = serde::Deserialize::deserialize(deserializer)?;
345 let sb = StringWrapper::from_str_safe(&s).ok_or_else(|| {
346 let buff = T::new();
347 let msg: String = format!("string that can fit into {} bytes", buff.as_ref().len());
348 D::Error::invalid_length(s.len(), &StringExpected(msg))
349 })?;
350 Ok(sb)
351 }
352}
353
354#[cfg(feature="use_serde")]
357struct StringExpected(String);
358#[cfg(feature="use_serde")]
359impl serde::de::Expected for StringExpected {
360 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
361 fmt::Display::fmt(&self.0, formatter)
362 }
363}
364
365unsafe impl<'a, T: ?Sized + Buffer> Buffer for &'a mut T {
366 fn as_ref(&self) -> &[u8] {
367 (**self).as_ref()
368 }
369 fn as_mut(&mut self) -> &mut [u8] {
370 (**self).as_mut()
371 }
372}
373
374unsafe impl<'a, T: ?Sized + Buffer> Buffer for Box<T> {
375 fn as_ref(&self) -> &[u8] {
376 (**self).as_ref()
377 }
378 fn as_mut(&mut self) -> &mut [u8] {
379 (**self).as_mut()
380 }
381}
382
383unsafe impl Buffer for Vec<u8> {
384 fn as_ref(&self) -> &[u8] {
385 self
386 }
387 fn as_mut(&mut self) -> &mut [u8] {
388 self
389 }
390}
391
392unsafe impl Buffer for [u8] {
393 fn as_ref(&self) -> &[u8] {
394 self
395 }
396 fn as_mut(&mut self) -> &mut [u8] {
397 self
398 }
399}
400
401macro_rules! array_impl {
402 ($($N: expr)+) => {
403 $(
404 unsafe impl Buffer for [u8; $N] {
405 fn as_ref(&self) -> &[u8] { self }
406 fn as_mut(&mut self) -> &mut [u8] { self }
407 }
408
409 impl OwnedBuffer for [u8; $N] {
410 fn new() -> Self { [0u8; $N] }
411 }
412 )+
413 }
414}
415
416array_impl! {
417 0 1 2 3 4 5 6 7 8 9
418 10 11 12 13 14 15 16 17 18 19
419 20 21 22 23 24 25 26 27 28 29
420 30 31 32
421 64 128 256 512 1024
422 2 * 1024
423 4 * 1024
424 8 * 1024
425 16 * 1024
426 32 * 1024
427 64 * 1024
428 128 * 1024
429 256 * 1024
430 512 * 1024
431 1024 * 1024
432 2 * 1024 * 1024
433 4 * 1024 * 1024
434 8 * 1024 * 1024
435 16 * 1024 * 1024
436 32 * 1024 * 1024
437 64 * 1024 * 1024
438 128 * 1024 * 1024
439 256 * 1024 * 1024
440 512 * 1024 * 1024
441 1024 * 1024 * 1024
442 100 1_000 10_000 100_000 1_000_000
443 10_000_000 100_000_000 1_000_000_000
444}
445
446#[cfg(test)]
447mod tests {
448 use std;
449 use std::cmp;
450 use std::hash;
451
452 #[cfg(feature="use_serde")]
453 extern crate serde_json;
454
455 use StringWrapper;
456
457 #[test]
458 fn traits() {
459 #[derive(Eq, PartialEq, Ord, PartialOrd)]
461 struct Foo {
462 x: StringWrapper<[u8; 64]>,
463 }
464 }
465
466 #[test]
467 fn eq() {
468 let mut s = StringWrapper::<[u8; 3]>::new(*b"000");
469 assert_eq!(s, s);
470 s.push_str("foo");
471 let mut s2 = StringWrapper::<[u8; 3]>::new(*b"000");
472 s2.push_str("foo");
473 assert_eq!(s, s2);
474
475 let mut s3 = StringWrapper::<[u8; 3]>::new(*b"000");
476 s3.push_str("bar");
477 assert!(s != s3);
478 }
479
480 #[test]
481 fn eq_only_to_length() {
482 let a = StringWrapper::<[u8; 5]>::new(*b"aaaaa");
483 let b = StringWrapper::<[u8; 5]>::new(*b"bbbbb");
484 assert_eq!(a, b);
485 }
486
487 #[test]
488 fn ord() {
489 let mut s = StringWrapper::<[u8; 3]>::new(*b"000");
490 let mut s2 = StringWrapper::<[u8; 3]>::new(*b"000");
491 s.push_str("a");
492 s2.push_str("b");
493 assert_eq!(s.partial_cmp(&s2), Some(cmp::Ordering::Less));
494 assert_eq!(s.cmp(&s2), cmp::Ordering::Less);
495 }
496
497 #[test]
498 fn ord_only_to_length() {
499 let mut s = StringWrapper::<[u8; 3]>::new(*b"000");
500 let mut s2 = StringWrapper::<[u8; 3]>::new(*b"111");
501 assert_eq!(s.partial_cmp(&s2), Some(cmp::Ordering::Equal));
502 assert_eq!(s.cmp(&s2), cmp::Ordering::Equal);
503
504 s.push_str("aa");
505 s2.push_str("aa");
506 assert_eq!(s.partial_cmp(&s2), Some(cmp::Ordering::Equal));
507 assert_eq!(s.cmp(&s2), cmp::Ordering::Equal);
508 }
509
510 #[cfg(test)]
511 fn hash<T: hash::Hash>(t: &T) -> u64 {
512 let mut h = std::collections::hash_map::DefaultHasher::new();
514 t.hash(&mut h);
515 hash::Hasher::finish(&h)
516 }
517
518 #[test]
519 fn hash_only_to_length() {
520 let mut s = StringWrapper::<[u8; 64]>::new([0u8; 64]);
521 let mut s2 = StringWrapper::<[u8; 64]>::new([1u8; 64]);
522 assert_eq!(hash(&s), hash(&s2));
523 s.push_str("a");
524 assert!(hash(&s) != hash(&s2));
525 s2.push_str("a");
526 assert_eq!(hash(&s), hash(&s2));
527 }
528
529 #[test]
530 fn from_str() {
531 let s: StringWrapper<[u8; 64]> = StringWrapper::from_str("OMG!");
532 let mut s2 = StringWrapper::new([0u8; 64]);
533 s2.push_str("OMG!");
534 assert_eq!(s, s2);
535 }
536
537 #[test]
538 fn it_works() {
539 let mut s = StringWrapper::new([0; 10]);
540 assert_eq!(&*s, "");
541 assert_eq!(s.len(), 0);
542 assert_eq!(s.capacity(), 10);
543 assert_eq!(s.extra_capacity(), 10);
544
545 assert_eq!(&*s, "");
546 assert_eq!(s.len(), 0);
547 assert_eq!(s.capacity(), 10);
548 assert_eq!(s.extra_capacity(), 10);
549
550 s.push_str("a");
551 assert_eq!(&*s, "a");
552 assert_eq!(s.len(), 1);
553 assert_eq!(s.capacity(), 10);
554 assert_eq!(s.extra_capacity(), 9);
555
556 assert_eq!(s.push('é'), Ok(()));
557 assert_eq!(&*s, "aé");
558 assert_eq!(s.len(), 3);
559 assert_eq!(s.capacity(), 10);
560 assert_eq!(s.extra_capacity(), 7);
561
562 assert_eq!(s.push_partial_str("~~~"), Ok(()));
563 assert_eq!(&*s, "aé~~~");
564 assert_eq!(s.len(), 6);
565 assert_eq!(s.capacity(), 10);
566 assert_eq!(s.extra_capacity(), 4);
567
568 assert_eq!(s.push_partial_str("hello"), Err(4));
569 assert_eq!(&*s, "aé~~~hell");
570 assert_eq!(s.len(), 10);
571 assert_eq!(s.capacity(), 10);
572 assert_eq!(s.extra_capacity(), 0);
573
574 s.truncate(6);
575 assert_eq!(&*s, "aé~~~");
576 assert_eq!(s.len(), 6);
577 assert_eq!(s.capacity(), 10);
578 assert_eq!(s.extra_capacity(), 4);
579
580 assert_eq!(s.push_partial_str("_🌠"), Err(1));
581 assert_eq!(&*s, "aé~~~_");
582 assert_eq!(s.len(), 7);
583 assert_eq!(s.capacity(), 10);
584 assert_eq!(s.extra_capacity(), 3);
585
586 assert_eq!(s.push('🌠'), Err(()));
587 assert_eq!(&*s, "aé~~~_");
588 assert_eq!(s.len(), 7);
589 assert_eq!(s.capacity(), 10);
590 assert_eq!(s.extra_capacity(), 3);
591
592
593 let buffer: [u8; 10] = s.clone().into_buffer();
594 assert_eq!(&buffer, b"a\xC3\xA9~~~_ell");
595 assert_eq!(format!("{}", s), "aé~~~_");
596 assert_eq!(format!("{:?}", s), r#""aé~~~_""#);
597
598 assert_eq!(s.push_partial_str("ô!?"), Err(3));
599 assert_eq!(&*s, "aé~~~_ô!");
600 assert_eq!(s.len(), 10);
601 assert_eq!(s.capacity(), 10);
602 assert_eq!(s.extra_capacity(), 0);
603 }
604
605 #[cfg(feature="use_serde")]
606 #[test]
607 fn test_serde() {
608 let mut s = StringWrapper::new([0u8; 64]);
609 s.push_str("foobar");
610 let json = serde_json::to_string(&s).unwrap();
611 assert_eq!(json, "\"foobar\"");
612 let s2 = serde_json::from_str(&json).unwrap();
613 assert_eq!(s, s2);
614 }
615
616 #[cfg(feature="use_serde")]
617 #[test]
618 fn deserialize_too_long() {
619 let json = "\"12345\"";
620 match serde_json::from_str::<StringWrapper<[u8; 3]>>(&json) {
621 Err(e) => {
622 assert_eq!(format!("{}", e),
623 "invalid length 5, expected string that can fit into 3 bytes")
624 }
625 Ok(x) => panic!("Expected error, got success: {:?}", x),
626 }
627 }
628
629 #[test]
630 fn clone() {
631 let s = StringWrapper::new([0u8; 64]);
632 let y: StringWrapper<[u8; 64]> = s.clone();
633 println!("s: {}, y: {}", s, y);
634 }
635}