Crate async_serde

Source
Expand description

§Async Serde

This is a crate for async fn serde. It’s not necessarily more efficient, merely different. It allows using serde to interact with data formats (like JSON, etc) directly instead of going through deserialization.

Its main feature is the ability to trivially apply non-deterministic (in the automaton sense) transformations directly onto the deserialization process. This is particularly useful if you happen to be making a jq clone that operates directly on the data stream instead of loading the whole data stream into an in-memory data structure first.

§Note

Note that the types Instructor and Step can be passed around freely in a Run impl. While not unsound, this can lead to hard-to-debug errors. It’s recommended to only use these as indicated in these examples, to avoid the hard-to-debug runtime errors.

§Examples

use std::borrow::Cow;

use async_serde::Deserialize;
use async_serde::Inspect;
use async_serde::Instructor;
use async_serde::Run;
use async_serde::Visit;
use async_trait::async_trait;

struct Foo;
#[async_trait(?Send)]
impl<'de, E: serde::de::Error> Run<'de, E> for Foo {
    type Output = Cow<'de, str>;
    async fn run(
        self,
        instructor: Instructor<'_, 'de>
    ) -> Result<Self::Output, E> {
        let step = instructor.ask(Deserialize::String).unwrap().await;
        match step.kind() {
            Visit::Str => {
                step.inspect_string(|s| {
                    match s {
                        Inspect::Borrowed(s) => Cow::from(s),
                        Inspect::Owned(s) => Cow::from(String::from(s)),
                        Inspect::Buffered(s) => Cow::from(s.to_owned()),
                    }
                }).ok_or_else(|| E::custom("wrong type"))
            },
            _ => Err(E::custom("wrong type")),
        }
    }
}

fn main() {
    let mut json = serde_json::Deserializer::from_str("\"hello\"");
    let exec = async_serde::Executor::new(&mut json);
    // this is returning an Result<Option<Cow<'de, str>>, Error>
    let res = exec.run::<_, serde_json::Error>(Foo);
    assert_eq!(res.unwrap(), "hello");
}
use std::borrow::Cow;

use async_serde::Deserialize;
use async_serde::Inspect;
use async_serde::Instructor;
use async_serde::Run;
use async_serde::Visit;
use async_trait::async_trait;

struct Foo;
#[async_trait(?Send)]
impl<'de, E: serde::de::Error> Run<'de, E> for Foo {
    type Output = [Vec<Cow<'de, str>>; 2];
    async fn run(
        self,
        instructor: Instructor<'_, 'de>
    ) -> Result<Self::Output, E> {
        let mut step = instructor.ask(Deserialize::Seq).unwrap().await;
        match step.kind() {
            Visit::Seq => {
                let step2 = step.cloned();
                match futures::join!(
                    step.inspect_seq(|s| async move {
                        // TODO
                        Ok(Vec::new())
                    }).ok_or_else(|| E::custom("wrong type"))?,
                    step2.inspect_seq(|s| async move {
                        // TODO
                        Ok(Vec::new())
                    }).ok_or_else(|| E::custom("wrong type"))?
                ) {
                    (a, b) => Ok([a?, b?])
                }
            },
            _ => Err(E::custom("wrong type")),
        }
    }
}

fn main() {
    let mut json = serde_json::Deserializer::from_str("[\"a\", \"b\"]");
    let exec = async_serde::Executor::new(&mut json);
    // this is returning an Result<Option<Cow<'de, str>>, Error>
    let res = exec.run::<_, serde_json::Error>(Foo).unwrap();
    assert_eq!(res[0], &[Cow::from("a"), "b".into()][..]);
    assert_eq!(res[1], &[Cow::from("a"), "b".into()][..]);
}

Structs§

Executor
The Async Serde executor.
Instructor
Allows passing instructions to the Async Serde executor.
SeqInstructor
Allows passing instructions to the Async Serde executor to iterate a sequence.
Step
Allows retrieving values from the Async Serde executor.

Enums§

Deserialize
What you expect the executor to do.
Inspect
A deserialized buffer for inspection.
Visit
What the executor expects you to do.

Traits§

Run