Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't figure out why this code won't compile #31

Open
Keithcat1 opened this issue Jun 16, 2021 · 5 comments
Open

Can't figure out why this code won't compile #31

Keithcat1 opened this issue Jun 16, 2021 · 5 comments

Comments

@Keithcat1
Copy link

I have the following bit of code and it won't compile:
use {serde::{de::DeserializeOwned}, std::io::Read, genawaiter::{yield_, stack::let_gen}};

fn stream_iter<T: DeserializeOwned, U: Read>(reader: U) -> impl Iterator<Item=serde_json::Result> {
let_gen!(output, {
loop {
yield_!(serde_json::from_reader<U, T>(reader));
}
});
return output.into_iter();
}
fn main() {
}
The generator is supposed to read values of type T from an std::io::Read by using serde_json to deserialize the data.
The error I am getting is this:
error: no rules expected the token @
--> src\bin\stdin_json.rs:4:2
|
4 | / let_gen!(output, {
5 | | loop {
6 | | yield_!(serde_json::from_reader<U, T>(reader));
7 | | }
8 | | });
| |_______^ no rules expected this token in macro call
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro
-backtrace for more info)

error: aborting due to previous error

Thanks for the library BTW. Generators are cool!

@DevinR528
Copy link
Collaborator

I think you just need a turbofish on serde_json::from_reader::<U, T>(reader) but you will run into other problems with U not being copy or clone

fn stream_iter<T: DeserializeOwned, U: Read + Clone>(reader: U) -> Vec<serde_json::Result<T>> {
    let_gen!(output, {
        loop {
            yield_!(serde_json::from_reader::<U, T>(reader.clone()));
        }
    });
    output.into_iter().collect()
}
fn main() {}

This works but may not be what you need?

@Keithcat1
Copy link
Author

Keithcat1 commented Jun 17, 2021 via email

@DevinR528
Copy link
Collaborator

Lifetime issues because T and U need to be 'static and if you add that bound when the macro expands the output variable is a &mut Gen so the function can't return a reference owned by the function.

Here is the expanded output

fn gener() {
    use std::io::Read;
    use genawaiter::{stack::let_gen, yield_};
    use serde::de::DeserializeOwned;
    fn stream_iter<T: DeserializeOwned + 'static, U: Read + Clone + 'static>(
        reader: U,
    ) -> Vec<serde_json::Result<T>> {
        let mut shelf = ::genawaiter::stack::Shelf::new();
        let mut generator = unsafe {
            ::genawaiter::stack::Gen::new(&mut shelf, {
                #[allow(dead_code)]
                enum ProcMacroHack {
                    Value = ( "{ loop  { yield_!(serde_json :: from_reader :: < U, T > (reader.clone())); } }" , 0 ) . 1 , }
                |__private_co_arg__: ::genawaiter::stack::Co<'_, _, _>| async move {
                    loop {
                        __private_co_arg__
                            .yield_(serde_json::from_reader::<U, T>(reader.clone()))
                            .await;
                    }
                }
            })
        };
        let output = &mut generator;
        output.into_iter().collect()
    }
    fn main() {}
}

You could pass in a callback or something like that since your right collecting into a Vec kinda defeats the purpose.

@Keithcat1
Copy link
Author

Keithcat1 commented Jun 17, 2021 via email

@DevinR528
Copy link
Collaborator

Well this works but you can't have T because of type limitations

fn sterff() {
    use std::io::Read;

    use genawaiter::{rc::gen, yield_};
    use serde::de::DeserializeOwned;

    fn stream_iter<U: Read>(
        mut reader: impl Iterator<Item = U>,
    ) -> impl Iterator<Item = serde_json::Result<serde_json::Value>> {
        gen!({
            loop {
                yield_!(serde_json::from_reader::<U, serde_json::Value>(
                    reader.next().unwrap()
                ))
            }
        })
        .into_iter()
    }

    let reader: Vec<&[u8]> = vec![b"{}", b"\"string\"", b"123"];
    for x in stream_iter(reader.into_iter()) {
        println!("{:?}", x)
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants