1use std::ffi::OsStr;
2
3use clap::{builder::TypedValueParser, Arg, Command};
4use nom::{character::complete::char, combinator::map, sequence::separated_pair, IResult};
5
6use super::{
7 value::{parse_value, Value},
8 xattr::{parse_xattr, Xattr},
9};
10
11#[derive(Clone)]
12pub struct Assignment {
13 pub xattr: Xattr,
14 pub value: Value,
15}
16impl Assignment {
17 pub fn new(xattr: Xattr, value: Value) -> Self {
18 Self { xattr, value }
19 }
20}
21
22impl std::fmt::Display for Assignment {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
24 write!(f, "{}={}", self.xattr, self.value)
25 }
26}
27
28pub fn parse_assignment(i: &[u8]) -> IResult<&[u8], Assignment> {
29 map(
30 separated_pair(parse_xattr, char('='), parse_value),
31 |(xattr, value)| Assignment { xattr, value },
32 )(i)
33}
34
35#[derive(Clone)]
36pub struct AssignmentParser;
37impl TypedValueParser for AssignmentParser {
38 type Value = Assignment;
39
40 fn parse_ref(
41 &self,
42 _cmd: &Command,
43 _arg: Option<&Arg>,
44 value: &OsStr,
45 ) -> Result<Self::Value, clap::error::Error<clap::error::RichFormatter>> {
46 parse_assignment(value.to_string_lossy().as_bytes())
47 .map(|(_remainder, predicate)| predicate)
48 .map_err(|e| {
49 clap::error::Error::raw(
50 clap::error::ErrorKind::InvalidValue,
51 format!("Malformed WHERE clause: {}\n", e),
52 )
53 })
54 }
55}