0

我想tag_no_case用特定的字符串值包装解析器以便能够重用它们:

pub fn schema_parser<???>(???) -> ??? {
    tag_no_case("schema")
}

像这样使用

preceded(multispace0, schema_parser)(input)

我试图复制tag_no_case打字和其他一些随机方法,但对我没有任何帮助。

类型声明应该如何才能使用所示的自定义解析器?

4

1 回答 1

1

tag_no_case返回 aimpl Fn(Input) -> IResult<Input, Input, Error>这意味着我们必须从包装函数中返回类似的东西。

为简单起见,让我们跳过所有泛型而只使用&str,此时编译器会抱怨返回的类型“不够通用”,因为它在整个生命周期内都不是通用的。我们可以通过将生命周期参数添加到函数签名并使用该参数来注释返回类型来将其固定为单个生命周期。

最终完整的工作和编译示例:

// nom = "6.1.0"
use nom::{IResult, bytes::complete::tag_no_case, sequence::preceded};

fn schema_parser<'a>() -> impl Fn(&'a str) -> IResult<&'a str, &'a str> {
    tag_no_case("schema")
}

fn main() {
    let string = String::from("exampleschema");
    let mut parser = preceded(tag_no_case("example"), schema_parser());
    assert_eq!(parser(&string), Ok(("", "schema"))); // non-'static str
    assert_eq!(parser("exampleschema"), Ok(("", "schema"))); // 'static str
}
于 2021-01-31T17:49:36.763 回答