base64_ng/v2/
ordinary_string.rs1use alloc::string::String;
4
5use super::{
6 ordinary::OneShotError,
7 specifications::{Base64, Codec, CodecSettings},
8};
9
10#[derive(Clone, Debug, Eq, Hash, PartialEq)]
22pub struct Base64String<S: Codec> {
23 codec: Base64<S>,
24 encoded: String,
25}
26
27impl<S: Codec> Base64String<S> {
28 pub fn encode(codec: Base64<S>, input: &[u8]) -> Result<Self, OneShotError> {
33 let encoded = codec.encode_to_string(input)?;
34 Ok(Self { codec, encoded })
35 }
36
37 pub fn from_string(codec: Base64<S>, encoded: String) -> Result<Self, OneShotError> {
43 codec.validate(encoded.as_bytes())?;
44 Ok(Self { codec, encoded })
45 }
46
47 pub fn parse(codec: Base64<S>, encoded: &str) -> Result<Self, OneShotError> {
53 Self::parse_with_reserver(codec, encoded, |output, required| {
54 output
55 .try_reserve_exact(required)
56 .map_err(|_| OneShotError::AllocationFailed {
57 requested: required,
58 })
59 })
60 }
61
62 fn parse_with_reserver<F>(
63 codec: Base64<S>,
64 encoded: &str,
65 reserve: F,
66 ) -> Result<Self, OneShotError>
67 where
68 F: FnOnce(&mut String, usize) -> Result<(), OneShotError>,
69 {
70 codec.validate(encoded.as_bytes())?;
71 let mut owned = String::new();
72 reserve(&mut owned, encoded.len())?;
73 owned.push_str(encoded);
74 Ok(Self {
75 codec,
76 encoded: owned,
77 })
78 }
79
80 #[cfg(test)]
81 pub(super) fn parse_with_injected_reserver<F>(
82 codec: Base64<S>,
83 encoded: &str,
84 reserve: F,
85 ) -> Result<Self, OneShotError>
86 where
87 F: FnOnce(&mut String, usize) -> Result<(), OneShotError>,
88 {
89 Self::parse_with_reserver(codec, encoded, reserve)
90 }
91
92 #[must_use]
94 pub const fn codec(&self) -> &Base64<S> {
95 &self.codec
96 }
97
98 #[must_use]
100 pub fn settings(&self) -> CodecSettings {
101 self.codec.settings()
102 }
103
104 #[must_use]
109 pub fn as_str(&self) -> &str {
110 self.encoded.as_str()
111 }
112
113 #[must_use]
118 pub fn as_bytes(&self) -> &[u8] {
119 self.encoded.as_bytes()
120 }
121
122 #[must_use]
124 pub fn len(&self) -> usize {
125 self.encoded.len()
126 }
127
128 #[must_use]
130 pub fn is_empty(&self) -> bool {
131 self.encoded.is_empty()
132 }
133
134 pub fn decode(&self) -> Result<alloc::vec::Vec<u8>, OneShotError> {
136 self.codec.decode_to_vec(self.encoded.as_bytes())
137 }
138
139 pub fn decode_with_limit(
141 &self,
142 max_output_len: usize,
143 ) -> Result<alloc::vec::Vec<u8>, OneShotError> {
144 self.codec
145 .decode_to_vec_with_limit(self.encoded.as_bytes(), max_output_len)
146 }
147
148 #[must_use]
152 pub fn into_string(self) -> String {
153 self.encoded
154 }
155}
156
157impl<S: Codec> AsRef<str> for Base64String<S> {
158 fn as_ref(&self) -> &str {
159 self.as_str()
160 }
161}
162
163impl<S: Codec> AsRef<[u8]> for Base64String<S> {
164 fn as_ref(&self) -> &[u8] {
165 self.as_bytes()
166 }
167}
168
169impl<S: Codec> core::fmt::Display for Base64String<S> {
170 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
171 formatter.write_str(self.as_str())
172 }
173}