【问题标题】:How can I wrap a nom tag_no_case parser?如何包装 nom tag_no_case 解析器?
【发布时间】:2021-05-04 23:23:49
【问题描述】:

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

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

这样使用

preceded(multispace0, schema_parser)(input)

我尝试复制 tag_no_case 类型和其他一些随机方法,但没有任何效果。

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

【问题讨论】:

    标签: generics types rust closures nom


    【解决方案1】:

    tag_no_case 返回 impl Fn(Input) -&gt; IResult&lt;Input, Input, Error&gt;,这意味着我们必须从包装函数中返回类似的内容。

    为了简单起见,让我们跳过所有泛型,只使用&amp;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
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-03
      • 2021-08-15
      • 1970-01-01
      相关资源
      最近更新 更多