Code Monkey home page Code Monkey logo

Comments (4)

Marwes avatar Marwes commented on June 16, 2024

The first example you possible should typecheck fine, however it is possible you might have gotten a message that rust wasn't able to infer enough type information like this.

src/lib.rs:466:24: 466:28 error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]
src/lib.rs:466     let mut esc_char = char('\\').with(choice([
                                      ^~~~
src/lib.rs:466:24: 466:28 help: run `rustc --explain E0282` to see a detailed explanation
error: aborting due to previous error
Build failed, waiting for other jobs to finish...

If that is the case the only problem is that rust could not figure out what type is being parsed. So if you want to parse a raw string you can add a line.

esc_char.parse("Hello \n \"World\"");

Which shows to Rust that the parser should parse a string. (The problem is that rust needs to specialize the parser for a single input type but the parser could equivalently parse an iterator of chars instead of a &str). You could also define a generic function to make it work for both &str and iterators as in the expression example in https://marwes.github.io/combine/combine/index.html.

The reason your second example fails can be seen from the error message if you know what to look for. If you see this part it says it expected a reference (&) but got a type of With. The reason for this is that you didn't take the parsers by &mut which is necessary for them to be converted to a trait object.

expected &-ptr,
    found struct `combine::combinator::With`

So it should be:

    let esc_char = char('\\').with(choice::<&mut [&mut Parser<Input = &str, Output = char>; 6], _>(&mut [
        &mut char('\\').with(value('\\')),
        &mut char('"').with(value('"')),

(Since you are already specifying the length of the array you dont need to take that by &mut)

    let esc_char = char('\\').with(choice::<[&mut Parser<Input = &str, Output = char>; 6], _>([
        &mut char('\\').with(value('\\')),
        &mut char('"').with(value('"')),

from combine.

donhcd avatar donhcd commented on June 16, 2024

Thanks a ton for your help! I did some reading on trait objects and this was the cleanest code I could come up with that compiled:

    let mut ch = [
        &mut char('\\') as &mut _,
        &mut char('"') as &mut _,
        &mut char('0').with(value('\0')) as &mut _,
        &mut char('n').with(value('\n')) as &mut _,
        &mut char('t').with(value('\t')) as &mut _,
        &mut char('r').with(value('\r')) as &mut _,
    ];
    let esc_char = char('\\').with(choice::<&mut [&mut Parser<Input = &str, Output = char>; 6], _>(&mut ch));

Is this what you had in mind, or is there anything left that I can clean up here?

from combine.

Marwes avatar Marwes commented on June 16, 2024

Glad to be of help!

You could remove the as &mut _ parts which aren't necessary as the &mut With<...> will be coerced into trait objects automatically. And you don't need to pass the array by &mut either if you are already specifying its length

   let mut ch = [
        &mut char('\\'),
        &mut char('"'),
        &mut char('0').with(value('\0')),
        &mut char('n').with(value('\n')),
        &mut char('t').with(value('\t')),
        &mut char('r').with(value('\r')),
    ];
    let esc_char = char('\\').with(choice::<[&mut Parser<Input = &str, Output = char>; 6], _>(ch));

Alternatively if you don't want to specify the length of the array you could just pass it as a slice (&mut [T])

   let mut ch = [
        &mut char('\\'),
        &mut char('"'),
        &mut char('0').with(value('\0')),
        &mut char('n').with(value('\n')),
        &mut char('t').with(value('\t')),
        &mut char('r').with(value('\r')),
    ];
    let esc_char = char('\\').with(choice::<&mut [&mut Parser<Input = &str, Output = char>], _>(&mut ch));

(Haven't compiled it but it should work)

from combine.

donhcd avatar donhcd commented on June 16, 2024

okay, I managed to remove the casts with

let mut ch : &mut [&mut Parser<Input = &str, Output = char>] = &mut [
    &mut char('\\'),
    &mut char('0').with(value('\0')),
    &mut char('n').with(value('\n')),
    &mut char('t').with(value('\t')),
    &mut char('r').with(value('\r')),
];
let esc_char = char('\\').with(choice(&mut esc_choices))

I'm going to close this issue since it was never really an issue on the repo, but thanks again!

from combine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.