mirror of
https://github.com/containers/bootc.git
synced 2026-02-05 15:45:53 +01:00
kernel_cmdline: rename parse to parse_one and add new parse method
The (now-named) parse_one method is not particularly useful outside of
`CmdlineIter`. Almost always end users don't care about extra
unparsed content, they just want the `Option<Parameter>`.
This greatly improves ergnomics for users so they can create
parameters like...
`Parameter::parse("foo=bar").unwrap()`
... knowing at the call-site that "foo=bar" is a valid parameter so
the `unwrap()` is safe.
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
This commit is contained in:
@@ -43,7 +43,7 @@ impl<'a> Iterator for CmdlineIter<'a> {
|
||||
type Item = Parameter<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (param, rest) = Parameter::parse(self.0);
|
||||
let (param, rest) = Parameter::parse_one(self.0);
|
||||
self.0 = rest;
|
||||
param
|
||||
}
|
||||
@@ -266,6 +266,18 @@ pub struct Parameter<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Parameter<'a> {
|
||||
/// Attempt to parse a single command line parameter from a slice
|
||||
/// of bytes.
|
||||
///
|
||||
/// Returns `Some(Parameter)`, or `None` if a Parameter could not
|
||||
/// be constructed from the input. This occurs when the input is
|
||||
/// either empty or contains only whitespace.
|
||||
///
|
||||
/// Any remaining bytes not consumed from the input are discarded.
|
||||
pub fn parse<T: AsRef<[u8]> + ?Sized>(input: &'a T) -> Option<Self> {
|
||||
Self::parse_one(input).0
|
||||
}
|
||||
|
||||
/// Attempt to parse a single command line parameter from a slice
|
||||
/// of bytes.
|
||||
///
|
||||
@@ -276,7 +288,7 @@ impl<'a> Parameter<'a> {
|
||||
///
|
||||
/// Any remaining bytes not consumed from the input are returned
|
||||
/// as the second tuple item.
|
||||
pub fn parse<T: AsRef<[u8]> + ?Sized>(input: &'a T) -> (Option<Self>, &'a [u8]) {
|
||||
pub fn parse_one<T: AsRef<[u8]> + ?Sized>(input: &'a T) -> (Option<Self>, &'a [u8]) {
|
||||
let input = input.as_ref().trim_ascii_start();
|
||||
|
||||
if input.is_empty() {
|
||||
@@ -355,33 +367,33 @@ mod tests {
|
||||
|
||||
// convenience methods for tests
|
||||
fn param(s: &str) -> Parameter<'_> {
|
||||
Parameter::parse(s.as_bytes()).0.unwrap()
|
||||
Parameter::parse(s.as_bytes()).unwrap()
|
||||
}
|
||||
|
||||
fn param_utf8(s: &str) -> utf8::Parameter<'_> {
|
||||
utf8::Parameter::parse(s).0.unwrap()
|
||||
utf8::Parameter::parse(s).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parameter_parse() {
|
||||
let (p, rest) = Parameter::parse(b"foo");
|
||||
fn test_parameter_parse_one() {
|
||||
let (p, rest) = Parameter::parse_one(b"foo");
|
||||
let p = p.unwrap();
|
||||
assert_eq!(p.key.0, b"foo");
|
||||
assert_eq!(p.value, None);
|
||||
assert_eq!(rest, "".as_bytes());
|
||||
|
||||
// should consume one parameter and return the rest of the input
|
||||
let (p, rest) = Parameter::parse(b"foo=bar baz");
|
||||
let (p, rest) = Parameter::parse_one(b"foo=bar baz");
|
||||
let p = p.unwrap();
|
||||
assert_eq!(p.key.0, b"foo");
|
||||
assert_eq!(p.value, Some(b"bar".as_slice()));
|
||||
assert_eq!(rest, " baz".as_bytes());
|
||||
|
||||
// should return None on empty or whitespace inputs
|
||||
let (p, rest) = Parameter::parse(b"");
|
||||
let (p, rest) = Parameter::parse_one(b"");
|
||||
assert!(p.is_none());
|
||||
assert_eq!(rest, b"".as_slice());
|
||||
let (p, rest) = Parameter::parse(b" ");
|
||||
let (p, rest) = Parameter::parse_one(b" ");
|
||||
assert!(p.is_none());
|
||||
assert_eq!(rest, b"".as_slice());
|
||||
}
|
||||
@@ -418,7 +430,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_parameter_internal_key_whitespace() {
|
||||
let (p, rest) = Parameter::parse("foo bar=baz".as_bytes());
|
||||
let (p, rest) = Parameter::parse_one("foo bar=baz".as_bytes());
|
||||
let p = p.unwrap();
|
||||
assert_eq!(p.key.0, b"foo");
|
||||
assert_eq!(p.value, None);
|
||||
@@ -444,8 +456,7 @@ mod tests {
|
||||
assert!(failed_conversion.is_err());
|
||||
let mut p = b"foo=".to_vec();
|
||||
p.push(non_utf8_byte[0]);
|
||||
let (p, _rest) = Parameter::parse(&p);
|
||||
let p = p.unwrap();
|
||||
let p = Parameter::parse(&p).unwrap();
|
||||
assert_eq!(p.value, Some(non_utf8_byte.as_slice()));
|
||||
}
|
||||
|
||||
|
||||
@@ -195,6 +195,19 @@ impl PartialEq for ParameterKey<'_> {
|
||||
pub struct Parameter<'a>(bytes::Parameter<'a>);
|
||||
|
||||
impl<'a> Parameter<'a> {
|
||||
/// Attempt to parse a single command line parameter from a UTF-8
|
||||
/// string.
|
||||
///
|
||||
/// Returns `Some(Parameter)`, or `None` if a Parameter could not
|
||||
/// be constructed from the input. This occurs when the input is
|
||||
/// either empty or contains only whitespace.
|
||||
///
|
||||
/// Any remaining characters not consumed from the input are
|
||||
/// discarded.
|
||||
pub fn parse<T: AsRef<str> + ?Sized>(input: &'a T) -> Option<Self> {
|
||||
Self::parse_one(input).0
|
||||
}
|
||||
|
||||
/// Attempt to parse a single command line parameter from a UTF-8
|
||||
/// string.
|
||||
///
|
||||
@@ -205,8 +218,8 @@ impl<'a> Parameter<'a> {
|
||||
///
|
||||
/// Any remaining characters not consumed from the input are
|
||||
/// returned as the second tuple item.
|
||||
pub fn parse<T: AsRef<str> + ?Sized>(input: &'a T) -> (Option<Self>, &'a str) {
|
||||
let (bytes, rest) = bytes::Parameter::parse(input.as_ref().as_bytes());
|
||||
pub fn parse_one<T: AsRef<str> + ?Sized>(input: &'a T) -> (Option<Self>, &'a str) {
|
||||
let (bytes, rest) = bytes::Parameter::parse_one(input.as_ref().as_bytes());
|
||||
|
||||
// SAFETY: we know this is valid UTF-8 since input is &str,
|
||||
// and `rest` is a subslice of that &str which was split on
|
||||
@@ -288,29 +301,29 @@ mod tests {
|
||||
|
||||
// convenience method for tests
|
||||
fn param(s: &str) -> Parameter<'_> {
|
||||
Parameter::parse(s).0.unwrap()
|
||||
Parameter::parse(s).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parameter_parse() {
|
||||
let (p, rest) = Parameter::parse("foo");
|
||||
fn test_parameter_parse_one() {
|
||||
let (p, rest) = Parameter::parse_one("foo");
|
||||
let p = p.unwrap();
|
||||
assert_eq!(p.key(), "foo".into());
|
||||
assert_eq!(p.value(), None);
|
||||
assert_eq!(rest, "");
|
||||
|
||||
// should consume one parameter and return the rest of the input
|
||||
let (p, rest) = Parameter::parse("foo=bar baz");
|
||||
let (p, rest) = Parameter::parse_one("foo=bar baz");
|
||||
let p = p.unwrap();
|
||||
assert_eq!(p.key(), "foo".into());
|
||||
assert_eq!(p.value(), Some("bar"));
|
||||
assert_eq!(rest, " baz");
|
||||
|
||||
// should return None on empty or whitespace inputs
|
||||
let (p, rest) = Parameter::parse("");
|
||||
let (p, rest) = Parameter::parse_one("");
|
||||
assert!(p.is_none());
|
||||
assert_eq!(rest, "");
|
||||
let (p, rest) = Parameter::parse(" ");
|
||||
let (p, rest) = Parameter::parse_one(" ");
|
||||
assert!(p.is_none());
|
||||
assert_eq!(rest, "");
|
||||
}
|
||||
@@ -341,7 +354,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_parameter_internal_key_whitespace() {
|
||||
let (p, rest) = Parameter::parse("foo bar=baz");
|
||||
let (p, rest) = Parameter::parse_one("foo bar=baz");
|
||||
let p = p.unwrap();
|
||||
assert_eq!(p.key(), "foo".into());
|
||||
assert_eq!(p.value(), None);
|
||||
@@ -393,19 +406,19 @@ mod tests {
|
||||
#[test]
|
||||
fn test_parameter_tryfrom() {
|
||||
// ok switch
|
||||
let p = bytes::Parameter::parse(b"foo").0.unwrap();
|
||||
let p = bytes::Parameter::parse(b"foo").unwrap();
|
||||
let utf = Parameter::try_from(p).unwrap();
|
||||
assert_eq!(utf.key(), "foo".into());
|
||||
assert_eq!(utf.value(), None);
|
||||
|
||||
// ok key/value
|
||||
let p = bytes::Parameter::parse(b"foo=bar").0.unwrap();
|
||||
let p = bytes::Parameter::parse(b"foo=bar").unwrap();
|
||||
let utf = Parameter::try_from(p).unwrap();
|
||||
assert_eq!(utf.key(), "foo".into());
|
||||
assert_eq!(utf.value(), Some("bar".into()));
|
||||
|
||||
// bad switch
|
||||
let p = bytes::Parameter::parse(b"f\xffoo").0.unwrap();
|
||||
let p = bytes::Parameter::parse(b"f\xffoo").unwrap();
|
||||
let e = Parameter::try_from(p);
|
||||
assert_eq!(
|
||||
e.unwrap_err().to_string(),
|
||||
@@ -413,7 +426,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// bad key/value
|
||||
let p = bytes::Parameter::parse(b"foo=b\xffar").0.unwrap();
|
||||
let p = bytes::Parameter::parse(b"foo=b\xffar").unwrap();
|
||||
let e = Parameter::try_from(p);
|
||||
assert_eq!(
|
||||
e.unwrap_err().to_string(),
|
||||
|
||||
Reference in New Issue
Block a user