diff --git a/src/types.rs b/src/types.rs index fb4dada..cf80661 100644 --- a/src/types.rs +++ b/src/types.rs @@ -218,12 +218,28 @@ impl StatusCategory { pub struct Meta(String); impl Meta { + /// Creates a new "Meta" string. Fails if `meta` contains `\n`. pub fn new(meta: impl AsRef + Into) -> Result { ensure!(!meta.as_ref().contains("\n"), "Meta must not contain newlines"); Ok(Self(meta.into())) } + /// Cretaes a new "Meta" string. Truncates `meta` to before the first occurrence of `\n`. + pub fn new_lossy(meta: impl AsRef + Into) -> Self { + let meta = meta.as_ref(); + let newline_pos = meta.char_indices().position(|(_i, ch)| ch == '\n'); + + match newline_pos { + None => Self(meta.into()), + Some(newline_pos) => { + let meta = meta.get(..newline_pos).expect("northstar BUG"); + + Self(meta.into()) + } + } + } + pub fn empty() -> Self { Self::default() } @@ -329,3 +345,40 @@ impl From for Body { Self::Reader(Box::new(file)) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn meta_new_lossy_truncates() { + let meta = "foo\r\nbar\nquux"; + let meta = Meta::new_lossy(meta); + + assert_eq!(meta.as_str(), "foo\r"); + } + + #[test] + fn meta_new_lossy_no_truncate() { + let meta = "foo bar\r"; + let meta = Meta::new_lossy(meta); + + assert_eq!(meta.as_str(), "foo bar\r"); + } + + #[test] + fn meta_new_lossy_empty() { + let meta = ""; + let meta = Meta::new_lossy(meta); + + assert_eq!(meta.as_str(), ""); + } + + #[test] + fn meta_new_lossy_truncates_to_empty() { + let meta = "\n\n\n"; + let meta = Meta::new_lossy(meta); + + assert_eq!(meta.as_str(), ""); + } +}