Coverage Report

Created: 2026-06-15 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.3/src/concat.rs
Line
Count
Source
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::TryWriteable;
6
use crate::Writeable;
7
use core::fmt;
8
9
/// A [`Writeable`] that efficiently concatenates two other [`Writeable`]s.
10
///
11
/// See the [`concat_writeable!`] macro for a convenient way to make one of these.
12
///
13
/// # Examples
14
///
15
/// ```
16
/// use writeable::adapters::Concat;
17
/// use writeable::assert_writeable_eq;
18
///
19
/// assert_writeable_eq!(Concat("Number: ", 25), "Number: 25");
20
/// ```
21
///
22
/// With [`TryWriteable`]:
23
///
24
/// ```
25
/// use writeable::adapters::Concat;
26
/// use writeable::assert_try_writeable_eq;
27
/// use writeable::TryWriteable;
28
///
29
/// struct AlwaysPanic;
30
///
31
/// impl TryWriteable for AlwaysPanic {
32
///     type Error = &'static str;
33
///     fn try_write_to_parts<W: writeable::PartsWrite + ?Sized>(
34
///         &self,
35
///         _sink: &mut W,
36
///     ) -> Result<Result<(), Self::Error>, core::fmt::Error> {
37
///         // Unreachable panic: the first Writeable errors,
38
///         // so the second Writeable is not evaluated.
39
///         panic!("this is a test to demonstrate unreachable code")
40
///     }
41
/// }
42
///
43
/// let writeable0: Result<&str, &str> = Err("error message");
44
/// let writeable1 = AlwaysPanic;
45
///
46
/// assert_try_writeable_eq!(
47
///     Concat(writeable0, writeable1),
48
///     "error message",
49
///     Err("error message"),
50
/// )
51
/// ```
52
#[derive(Debug)]
53
#[allow(clippy::exhaustive_structs)] // designed for nesting
54
pub struct Concat<A, B>(pub A, pub B);
55
56
impl<A, B> Writeable for Concat<A, B>
57
where
58
    A: Writeable,
59
    B: Writeable,
60
{
61
    #[inline]
62
0
    fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result {
63
0
        self.0.write_to(sink)?;
64
0
        self.1.write_to(sink)
65
0
    }
66
    #[inline]
67
0
    fn write_to_parts<S: crate::PartsWrite + ?Sized>(&self, sink: &mut S) -> fmt::Result {
68
0
        self.0.write_to_parts(sink)?;
69
0
        self.1.write_to_parts(sink)
70
0
    }
71
    #[inline]
72
0
    fn writeable_length_hint(&self) -> crate::LengthHint {
73
0
        self.0.writeable_length_hint() + self.1.writeable_length_hint()
74
0
    }
75
}
76
77
impl<A, B, E> TryWriteable for Concat<A, B>
78
where
79
    A: TryWriteable<Error = E>,
80
    B: TryWriteable<Error = E>,
81
{
82
    type Error = E;
83
    #[inline]
84
0
    fn try_write_to<W: fmt::Write + ?Sized>(
85
0
        &self,
86
0
        sink: &mut W,
87
0
    ) -> Result<Result<(), Self::Error>, fmt::Error> {
88
0
        if let Err(e) = self.0.try_write_to(sink)? {
89
0
            return Ok(Err(e));
90
0
        }
91
0
        self.1.try_write_to(sink)
92
0
    }
93
    #[inline]
94
0
    fn try_write_to_parts<S: crate::PartsWrite + ?Sized>(
95
0
        &self,
96
0
        sink: &mut S,
97
0
    ) -> Result<Result<(), Self::Error>, fmt::Error> {
98
0
        if let Err(e) = self.0.try_write_to_parts(sink)? {
99
0
            return Ok(Err(e));
100
0
        }
101
0
        self.1.try_write_to_parts(sink)
102
0
    }
103
    #[inline]
104
0
    fn writeable_length_hint(&self) -> crate::LengthHint {
105
0
        self.0.writeable_length_hint() + self.1.writeable_length_hint()
106
0
    }
107
}
108
109
impl<A, B> fmt::Display for Concat<A, B>
110
where
111
    A: Writeable,
112
    B: Writeable,
113
{
114
    #[inline]
115
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116
0
        self.0.write_to(f)?;
117
0
        self.1.write_to(f)
118
0
    }
119
}
120
121
/// Returns a [`Writeable`] concatenating any number of [`Writeable`]s.
122
///
123
/// The macro resolves to a nested [`Concat`].
124
///
125
/// # Examples
126
///
127
/// ```
128
/// use writeable::assert_writeable_eq;
129
///
130
/// let concatenated = writeable::concat_writeable!("Health: ", 5, '/', 8);
131
///
132
/// assert_writeable_eq!(concatenated, "Health: 5/8");
133
/// ```
134
#[macro_export]
135
#[doc(hidden)] // macro
136
macro_rules! __concat_writeable {
137
    // Base case:
138
    ($x:expr) => ($x);
139
    // `$x` followed by at least one `$y,`
140
    ($x:expr, $($y:expr),+) => (
141
        // Call `concat_writeable!` recursively on the tail `$y`
142
        $crate::adapters::Concat($x, $crate::concat_writeable!($($y),+))
143
    )
144
}
145
#[doc(inline)]
146
pub use __concat_writeable as concat_writeable;