diff --git a/src/small.rs b/src/small.rs index 0c5be3e..3fd16cf 100644 --- a/src/small.rs +++ b/src/small.rs @@ -476,4 +476,39 @@ impl> Extend for SmallString } } -//TODO: SmallString: fmt::Write, io::Write impls when extending functions have been written +impl fmt::Write for SmallString +{ + #[inline] + fn write_str(&mut self, s: &str) -> fmt::Result { + (self.extend_from_str(s).len() == s.len()) + .then(|| ()).ok_or_else(|| fmt::Error::default()) + } + #[inline] + fn write_char(&mut self, c: char) -> fmt::Result { + let l = c.len_utf8(); + if self.is_allocated() { + let heap = unsafe {&mut self.inner.heap}; + let slice = unsafe { + std::slice::from_raw_parts_mut(heap.extend_allocate(l).as_ptr(), l) + }; + let _ = c.encode_utf8(slice); + } else if self.len() + l > SIZE { + // Shunt to heap with `c` + let mut buf = [0u8; mem::size_of::()]; + + unsafe { self.shunt_to_heap_with_unchecked( + std::iter::once_with(|| c.encode_utf8(&mut buf[..])).map(|&mut ref x| x) + ); + } + } else { + // Room in stack for `c` + let stack = unsafe{&mut self.inner.stack}; + let res = stack.write_char(c); + debug_assert!(res.is_ok(), "failed to append {c} to stack of len {}, when size is {SIZE} and char is only {l}", stack.len()); + let _ = res; + } + Ok(()) + } +} + +//TODO: SmallString: io::Write impls when extending functions have been written