ariadne icon indicating copy to clipboard operation
ariadne copied to clipboard

Problem specifying filename

Open cylewitruk opened this issue 2 years ago • 8 comments

Hi!

I'm trying to follow along with the provided examples and seem to be running into a problem when trying to specify the src_id (which I understand should be the filename). I'm currently getting the following result using () as src_id:

[03] Error: max-len indicator for list declarations must be greater than zero.
   ╭─[<unknown>:1:7]
   │
 1 │ (list -1 int)
   │       ─┬  
   │        ╰── max-len indicator for list declarations must be greater than zero.
───╯

Which is beautiful btw... but when I try to specify anything as src_id in the build function I can't seem to get it to work. In the example in README.me it looks like I should simply be able to provide a string slice, but I'm getting the following error:

the trait bound `(): std::convert::From<&str>` is not satisfied
the following other types implement trait `std::convert::From<T>`:
  <(T,) as std::convert::From<[T; 1]>> // etc.. etc..

I have tried both:

Report::build(ReportKind::Error, "hello", err.span().start)

and

.print(("hello", ariadne::Source::from(src)))

according to the examples...

cylewitruk avatar Oct 20 '23 16:10 cylewitruk

The second argument of print is any type that implements Cache<SrcId>, where SrcId is the identifier for the source file. As a convenience, Source implements Cache<()> (i.e: no source ID is required because it's just a standalone source, so the source ID is ()). That's why it's asking that (): From<&str>: it's trying to convert the "hello" into a () to use as the source ID.

The solution is to use a different cache type. There's a function called sources which accepts a list of (SrcId, Source) pairs.

Report::build(ReportKind::Error, "hello", err.span().start)
    ...
    .print(sources([
        ("hello", Source::from(src)),
        ...
    ]))

Alternatively you have FnCache, which allows you to treat arbitrary functions as a cache.

For the record: I'm not particularly happy with this API generally, and I'd like to find the time to redesign it such that this sort of confusion happens less.

zesterer avatar Oct 20 '23 16:10 zesterer

Thanks for the quick answer! Haha the API itself isn't a problem just as long as it's easy to understand :)

I tried your suggestion now but still having trouble... it's probably something stupid like a comma or something...

fn report(self, src: &str) -> Self {
            let result = self.clone().into_result();
            if let Err(errs) = result {
                for err in errs {
                    Report::build(ReportKind::Error, "clarity contract", err.span().start)
                        .with_code(3)
                        .with_message(err.to_string())
                        .with_label(
                            Label::new(err.span().into_range())
                                .with_message(err.reason().to_string())
                                .with_color(Color::Red),
                        )
                        .finish()
                        .print(sources([
                            ("clarity contract", ariadne::Source::from(src))
                        ]))
                        .unwrap();
                }
            }
            self
        }

and getting several errors: image

  1. the trait bound `(): std::convert::From<&str>` is not satisfied the following other types implement trait `std::convert::From<T>`: <(T,) as std::convert::From<[T; 1]>>
  2. the trait bound `ariadne::Source: std::convert::AsRef<str>` is not satisfied the trait `std::convert::AsRef<str>` is not implemented for `ariadne::Source`

Maybe worth mentioning that I'm lexing with Logos (which also has a Source type, hence why it's explicitly annotated). Note2: the snippet above is from test-helper code which is why it's being wrapped.

This is the code that works (but produces the <unknown>: image

cylewitruk avatar Oct 20 '23 17:10 cylewitruk

The problem is that your span also needs to have a matching SrcId. Using a Range<usize> works, but it gives you a SrcId of (). You can either implement Span for your own type, or use one of those that allows for a SrcId, such as a tuple (see the implementations of Span in the docs).

zesterer avatar Oct 21 '23 08:10 zesterer

I had the same problem, can you update the documentation

hhamud avatar Nov 11 '23 23:11 hhamud

Update it in what respect?

zesterer avatar Nov 13 '23 11:11 zesterer

Update it in what respect?

What would have helped me solve this myself is probably a "Specifying the filename" docs/wiki section or a simple example with the name "custom_filename.rs" or something similar that just makes it easier to find :)

cylewitruk avatar Nov 13 '23 12:11 cylewitruk

Update it in what respect?

like what @cylewitruk has stated better documentation on anything that is unusual. I've been using your chumsky library as an extension of ariadne docs so you could pull some of examples from there

hhamud avatar Nov 13 '23 17:11 hhamud

I just specified it everywhere and it works. Added filename to label

fn report(self, src: &str) -> Self {
    let result = self.clone().into_result();
    if let Err(errs) = result {
        for err in errs {
            Report::build(ReportKind::Error, "clarity contract", err.span().start)
                .with_code(3)
                .with_message(err.to_string())
                .with_label(
                    Label::new(("clarity contact", err.span().into_range()))
                        .with_message(err.reason().to_string())
                        .with_color(Color::Red),
                )
                .finish()
                .print(("clarity contract", ariadne::Source::from(src)))
                .unwrap();
        }
    }
    self
}

artegoser avatar Apr 08 '24 17:04 artegoser