Skip to content

Commit c759117

Browse files
authored
password-hash: add ParamsString::add_b64_bytes method (#722)
Adds a helper method for encoding bytes into a `ParamsString` as "B64".
1 parent 24f1d83 commit c759117

File tree

1 file changed

+45
-6
lines changed

1 file changed

+45
-6
lines changed

password-hash/src/params.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::errors::InvalidValue;
44
use crate::{
55
value::{Decimal, Value},
6-
Error, Ident, Result,
6+
Encoding, Error, Ident, Result,
77
};
88
use core::{
99
convert::{TryFrom, TryInto},
@@ -50,22 +50,51 @@ impl ParamsString {
5050
Self::default()
5151
}
5252

53+
/// Add the given byte value to the [`ParamsString`], encoding it as "B64".
54+
pub fn add_b64_bytes<'a>(&mut self, name: impl TryInto<Ident<'a>>, bytes: &[u8]) -> Result<()> {
55+
if !self.is_empty() {
56+
self.0
57+
.write_char(PARAMS_DELIMITER)
58+
.map_err(|_| Error::ParamsMaxExceeded)?
59+
}
60+
61+
let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?;
62+
63+
// Add param name
64+
let offset = self.0.length;
65+
if write!(self.0, "{}=", name).is_err() {
66+
self.0.length = offset;
67+
return Err(Error::ParamsMaxExceeded);
68+
}
69+
70+
// Encode B64 value
71+
let offset = self.0.length as usize;
72+
let written = Encoding::B64
73+
.encode(bytes, &mut self.0.bytes[offset..])?
74+
.len();
75+
76+
self.0.length += written as u8;
77+
Ok(())
78+
}
79+
80+
/// Add a key/value pair with a decimal value to the [`ParamsString`].
81+
pub fn add_decimal<'a>(&mut self, name: impl TryInto<Ident<'a>>, value: Decimal) -> Result<()> {
82+
let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?;
83+
self.add(name, value)
84+
}
85+
5386
/// Add a key/value pair with a string value to the [`ParamsString`].
5487
pub fn add_str<'a>(
5588
&mut self,
5689
name: impl TryInto<Ident<'a>>,
5790
value: impl TryInto<Value<'a>>,
5891
) -> Result<()> {
5992
let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?;
93+
6094
let value = value
6195
.try_into()
6296
.map_err(|_| Error::ParamValueInvalid(InvalidValue::InvalidFormat))?;
63-
self.add(name, value)
64-
}
6597

66-
/// Add a key/value pair with a decimal value to the [`ParamsString`].
67-
pub fn add_decimal<'a>(&mut self, name: impl TryInto<Ident<'a>>, value: Decimal) -> Result<()> {
68-
let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?;
6998
self.add(name, value)
7099
}
71100

@@ -311,6 +340,16 @@ mod tests {
311340
assert_eq!(params.get_decimal("c").unwrap(), 3);
312341
}
313342

343+
#[test]
344+
#[cfg(feature = "alloc")]
345+
fn add_b64_bytes() {
346+
let mut params = ParamsString::new();
347+
params.add_b64_bytes("a", &[1]).unwrap();
348+
params.add_b64_bytes("b", &[2, 3]).unwrap();
349+
params.add_b64_bytes("c", &[4, 5, 6]).unwrap();
350+
assert_eq!(params.to_string(), "a=AQ,b=AgM,c=BAUG");
351+
}
352+
314353
#[test]
315354
fn duplicate_names() {
316355
let name = Ident::new("a");

0 commit comments

Comments
 (0)