How to handle heterogeneous optional fields #542
-
I'm parsing a file format (tmpfiles.d from systemd as it happens) and the format consists of lines of 7 heterogeneous fields and all but the first two are optional. For example, all of the following are valid:
So far my main parser looks like this, and can handle the full line format: fn directive(i: &mut &str) -> PResult<Line> {
let entry_type = any_string.context(StrContext::Label("entry type"));
let path = any_string.context(StrContext::Label("path"));
let mode = mode_parser.context(StrContext::Label("mode"));
let user = id_parser.context(StrContext::Label("user"));
let group = id_parser.context(StrContext::Label("group"));
let age = optional_string.context(StrContext::Label("age"));
// Type of argument depends on entry type, parse in a higher layer where we untangle the multitude of modifiers entry type has
let argument = optional_string.context(StrContext::Label("argument"));
(
entry_type, space1, path, space1, mode, space1, user, space1, group, space1, age, space1,
argument,
)
.map(
|(entry_type, _, path, _, mode, _, user, _, group, _, age, _, argument)| Directive {
entry_type,
path,
mode,
user,
group,
age,
argument,
},
)
.parse_next(i)
}
/// Low level parser that doesn't make a difference between entry types
#[derive(Debug, PartialEq, Eq)]
pub(super) struct Line {
entry_type: String,
path: String,
mode: Option<Mode>,
user: Option<Id>,
group: Option<Id>,
age: Option<String>,
argument: Option<String>,
} I could write this with |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Not to sure of the schema but it sounds like you can use |
Beta Was this translation helpful? Give feedback.
This seems to work: