[][src]Module sval::stream

A stream for datastructures.

The Stream trait

A Stream is a type that receives and works with abstract data-structures.

Streams without state

Implement the Stream trait to visit the structure of a Value:

use sval::stream::{self, Stream};

struct Fmt;

impl Stream for Fmt {
    fn fmt(&mut self, v: stream::Arguments) -> stream::Result {
        println!("{}", v);

        Ok(())
    }

    fn i128(&mut self, v: i128) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn u128(&mut self, v: u128) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn f64(&mut self, v: f64) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn bool(&mut self, v: bool) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn str(&mut self, v: &str) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn none(&mut self) -> stream::Result {
        self.fmt(stream::Arguments::debug(&()))
    }
}

A Stream might only care about a single kind of value. The following example overrides the provided u64 method to see whether a given value is a u64:

use sval::{
    value::Value,
    stream::{self, Stream, OwnedStream},
};

assert!(is_u64(42u64));

pub fn is_u64(v: impl Value) -> bool {
    OwnedStream::stream(IsU64(None), v)
        .map(|is_u64| is_u64.0.is_some())
        .unwrap_or(false)
}

struct IsU64(Option<u64>);
impl Stream for IsU64 {
    fn u64(&mut self, v: u64) -> stream::Result {
        self.0 = Some(v);

        Ok(())
    }
}

Streams with state

There are more methods on Stream that can be overriden for more complex datastructures like sequences and maps. The following example uses a stream::Stack to track the state of any sequences and maps and ensure they're valid:

use std::{fmt, mem};
use sval::stream::{self, stack, Stream, Stack};

struct Fmt {
    stack: stream::Stack,
    delim: &'static str,
}

impl Fmt {
    fn next_delim(pos: stack::Pos) -> &'static str {
        if pos.is_key() {
            return ": ";
        }

        if pos.is_value() || pos.is_elem() {
            return ", ";
        }

        return "";
    }
}

impl Stream for Fmt {
    fn fmt(&mut self, v: stream::Arguments) -> stream::Result {
        let pos = self.stack.primitive()?;

        let delim = mem::replace(&mut self.delim, Self::next_delim(pos));
        print!("{}{:?}", delim, v);

        Ok(())
    }

    fn i128(&mut self, v: i128) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn u128(&mut self, v: u128) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn f64(&mut self, v: f64) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn bool(&mut self, v: bool) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn str(&mut self, v: &str) -> stream::Result {
        self.fmt(stream::Arguments::debug(&v))
    }

    fn none(&mut self) -> stream::Result {
        self.fmt(stream::Arguments::debug(&()))
    }

    fn seq_begin(&mut self, _: Option<usize>) -> stream::Result {
        self.stack.seq_begin()?;

        let delim = mem::replace(&mut self.delim, "");
        print!("{}[", delim);

        Ok(())
    }

    fn seq_elem(&mut self) -> stream::Result {
        self.stack.seq_elem()?;

        Ok(())
    }

    fn seq_end(&mut self) -> stream::Result {
        let pos = self.stack.seq_end()?;

        self.delim = Self::next_delim(pos);
        print!("]");

        Ok(())
    }

    fn map_begin(&mut self, _: Option<usize>) -> stream::Result {
        self.stack.map_begin()?;

        let delim = mem::replace(&mut self.delim, "");
        print!("{}{{", delim);

        Ok(())
    }

    fn map_key(&mut self) -> stream::Result {
        self.stack.map_key()?;

        Ok(())
    }

    fn map_value(&mut self) -> stream::Result {
        self.stack.map_value()?;

        Ok(())
    }

    fn map_end(&mut self) -> stream::Result {
        let pos = self.stack.map_end()?;

        self.delim = Self::next_delim(pos);
        print!("}}");

        Ok(())
    }
}

By default, the Stack type has a fixed depth. That means deeply nested structures aren't supported. See the stream::Stack type for more details.

Re-exports

pub use self::stack::Stack;

Modules

stack

A fixed-size, stateful stack for streams.

Structs

Arguments

A formattable value.

OwnedStream

An owned stream wrapper.

RefMutStream

A borrowed stream wrapper.

Source

A streamable error.

Traits

Stream

A receiver for the structure of a value.

Type Definitions

Result

The type returned by streaming methods.