writeable/
parts_write_adapter.rs

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
5use crate::*;
6
7/// A wrapper around a type implementing [`fmt::Write`] that implements [`PartsWrite`].
8#[derive(Debug)]
9#[allow(clippy::exhaustive_structs)] // newtype
10pub struct CoreWriteAsPartsWrite<W: fmt::Write + ?Sized>(pub W);
11
12impl<W: fmt::Write + ?Sized> fmt::Write for CoreWriteAsPartsWrite<W> {
13    #[inline]
14    fn write_str(&mut self, s: &str) -> fmt::Result {
15        self.0.write_str(s)
16    }
17
18    #[inline]
19    fn write_char(&mut self, c: char) -> fmt::Result {
20        self.0.write_char(c)
21    }
22}
23
24impl<W: fmt::Write + ?Sized> PartsWrite for CoreWriteAsPartsWrite<W> {
25    type SubPartsWrite = CoreWriteAsPartsWrite<W>;
26
27    #[inline]
28    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
83pub struct WithPart<T: ?Sized> {
84    pub part: Part,
85    pub writeable: T,
86}
87
88impl<T: Writeable + ?Sized> Writeable for WithPart<T> {
89    #[inline]
90    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
91        self.writeable.write_to(sink)
92    }
93
94    #[inline]
95    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]
100    fn writeable_length_hint(&self) -> LengthHint {
101        self.writeable.writeable_length_hint()
102    }
103
104    #[inline]
105    fn write_to_string(&self) -> Cow<str> {
106        self.writeable.write_to_string()
107    }
108}
109
110impl<T: Writeable + ?Sized> fmt::Display for WithPart<T> {
111    #[inline]
112    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113        Writeable::write_to(&self, f)
114    }
115}