1 // This file is part of ICU4X. For terms of use, please see the file 2 // called LICENSE at the top level of the ICU4X source tree 3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). 4 5 use crate::*; 6 7 /// A wrapper around a type implementing [`fmt::Write`] that implements [`PartsWrite`]. 8 #[derive(Debug)] 9 #[allow(clippy::exhaustive_structs)] // newtype 10 pub struct CoreWriteAsPartsWrite<W: fmt::Write + ?Sized>(pub W); 11 12 impl<W: fmt::Write + ?Sized> fmt::Write for CoreWriteAsPartsWrite<W> { 13 #[inline] write_str(&mut self, s: &str) -> fmt::Result14 fn write_str(&mut self, s: &str) -> fmt::Result { 15 self.0.write_str(s) 16 } 17 18 #[inline] write_char(&mut self, c: char) -> fmt::Result19 fn write_char(&mut self, c: char) -> fmt::Result { 20 self.0.write_char(c) 21 } 22 } 23 24 impl<W: fmt::Write + ?Sized> PartsWrite for CoreWriteAsPartsWrite<W> { 25 type SubPartsWrite = CoreWriteAsPartsWrite<W>; 26 27 #[inline] with_part( &mut self, _part: Part, mut f: impl FnMut(&mut Self::SubPartsWrite) -> fmt::Result, ) -> fmt::Result28 fn with_part( 29 &mut self, 30 _part: Part, 31 mut f: impl FnMut(&mut Self::SubPartsWrite) -> fmt::Result, 32 ) -> fmt::Result { 33 f(self) 34 } 35 } 36 37 /// A [`Writeable`] that writes out the given part. 38 /// 39 /// # Examples 40 /// 41 /// ``` 42 /// use writeable::adapters::WithPart; 43 /// use writeable::assert_writeable_parts_eq; 44 /// use writeable::Part; 45 /// 46 /// // Simple usage: 47 /// 48 /// const PART: Part = Part { 49 /// category: "foo", 50 /// value: "bar", 51 /// }; 52 /// 53 /// assert_writeable_parts_eq!( 54 /// WithPart { 55 /// writeable: "Hello World", 56 /// part: PART 57 /// }, 58 /// "Hello World", 59 /// [(0, 11, PART)], 60 /// ); 61 /// 62 /// // Can be nested: 63 /// 64 /// const PART2: Part = Part { 65 /// category: "foo2", 66 /// value: "bar2", 67 /// }; 68 /// 69 /// assert_writeable_parts_eq!( 70 /// WithPart { 71 /// writeable: WithPart { 72 /// writeable: "Hello World", 73 /// part: PART 74 /// }, 75 /// part: PART2 76 /// }, 77 /// "Hello World", 78 /// [(0, 11, PART), (0, 11, PART2)], 79 /// ); 80 /// ``` 81 #[derive(Debug)] 82 #[allow(clippy::exhaustive_structs)] // public adapter 83 pub struct WithPart<T: ?Sized> { 84 pub part: Part, 85 pub writeable: T, 86 } 87 88 impl<T: Writeable + ?Sized> Writeable for WithPart<T> { 89 #[inline] write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result90 fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { 91 self.writeable.write_to(sink) 92 } 93 94 #[inline] write_to_parts<W: PartsWrite + ?Sized>(&self, sink: &mut W) -> fmt::Result95 fn write_to_parts<W: PartsWrite + ?Sized>(&self, sink: &mut W) -> fmt::Result { 96 sink.with_part(self.part, |w| self.writeable.write_to_parts(w)) 97 } 98 99 #[inline] writeable_length_hint(&self) -> LengthHint100 fn writeable_length_hint(&self) -> LengthHint { 101 self.writeable.writeable_length_hint() 102 } 103 104 #[inline] write_to_string(&self) -> Cow<str>105 fn write_to_string(&self) -> Cow<str> { 106 self.writeable.write_to_string() 107 } 108 } 109 110 impl<T: Writeable + ?Sized> fmt::Display for WithPart<T> { 111 #[inline] fmt(&self, f: &mut fmt::Formatter) -> fmt::Result112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 113 Writeable::write_to(&self, f) 114 } 115 } 116