Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  ser.rs   Sprache: unbekannt

 
use serde::ser::{self, Serialize};
use std::cell::Cell;
use std::error;
use std::fmt::{self, Display, Write};

/// Serialize the given data structure as a String of TOML.
///
/// Serialization can fail if `T`'s implementation of `Serialize` decides to
/// fail, if `T` contains a map with non-string keys, or if `T` attempts to
/// serialize an unsupported datatype such as an enum, tuple, or tuple struct.
pub fn to_string<T: ?Sized>(value: &T) -> Result<String, crate::Error>
where
    T: Serialize,
{
    let mut dst = String::with_capacity(128);
    value.serialize(&mut Serializer::new(&mut dst))?;
    Ok(dst)
}

#[derive(Debug)]
pub(crate) enum Error {
    /// Indicates that a Rust type was requested to be serialized but it was not
    /// supported.
    ///
    /// Currently the TOML format does not support serializing types such as
    /// enums, tuples and tuple structs.
    UnsupportedType,

    /// The key of all TOML maps must be strings, but serialization was
    /// attempted where the key of a map was not a string.
    KeyNotString,

    /// All values in a TOML table must be emitted before further tables are
    /// emitted. If a value is emitted *after* a table then this error is
    /// generated.
    ValueAfterTable,

    /// None was attempted to be serialized, but it's not supported.
    UnsupportedNone,

    /// A custom error which could be generated when serializing a particular
    /// type.
    Custom(String),
}

struct Serializer<'a> {
    dst: &'a mut String,
    state: State<'a>,
}

#[derive(Debug, Copy, Clone)]
enum ArrayState {
    Started,
    StartedAsATable,
}

#[derive(Debug, Clone)]
enum State<'a> {
    Table {
        key: &'a str,
        parent: &'a State<'a>,
        first: &'a Cell<bool>,
        table_emitted: &'a Cell<bool>,
    },
    Array {
        parent: &'a State<'a>,
        first: &'a Cell<bool>,
        type_: &'a Cell<Option<ArrayState>>,
        len: Option<usize>,
    },
    End,
}

struct SerializeSeq<'a, 'b> {
    ser: &'b mut Serializer<'a>,
    first: Cell<bool>,
    type_: Cell<Option<ArrayState>>,
    len: Option<usize>,
}

struct SerializeTable<'a, 'b> {
    ser: &'b mut Serializer<'a>,
    key: String,
    first: Cell<bool>,
    table_emitted: Cell<bool>,
}

impl<'a> Serializer<'a> {
    fn new(dst: &'a mut String) -> Serializer<'a> {
        Serializer {
            dst,
            state: State::End,
        }
    }

    fn display<T: Display>(&mut self, t: T, type_: ArrayState) -> Result<(), Error> {
        self.emit_key(type_)?;
        write!(self.dst, "{}", t).map_err(ser::Error::custom)?;
        if let State::Table { .. } = self.state {
            self.dst.push('\n');
        }
        Ok(())
    }

    fn emit_key(&mut self, type_: ArrayState) -> Result<(), Error> {
        self.array_type(type_);
        let state = self.state.clone();
        self._emit_key(&state)
    }

    // recursive implementation of `emit_key` above
    fn _emit_key(&mut self, state: &State) -> Result<(), Error> {
        match *state {
            State::End => Ok(()),
            State::Array {
                parent,
                first,
                type_,
                len,
            } => {
                assert!(type_.get().is_some());
                if first.get() {
                    self._emit_key(parent)?;
                }
                self.emit_array(first, len);
                Ok(())
            }
            State::Table {
                parent,
                first,
                table_emitted,
                key,
            } => {
                if table_emitted.get() {
                    return Err(Error::ValueAfterTable);
                }
                if first.get() {
                    self.emit_table_header(parent)?;
                    first.set(false);
                }
                self.escape_key(key)?;
                self.dst.push_str(" = ");
                Ok(())
            }
        }
    }

    fn emit_array(&mut self, first: &Cell<bool>, _len: Option<usize>) {
        if first.get() {
            self.dst.push('[');
        } else {
            self.dst.push_str(", ");
        }
    }

    fn array_type(&mut self, type_: ArrayState) {
        let prev = match self.state {
            State::Array { type_, .. } => type_,
            _ => return,
        };
        if prev.get().is_none() {
            prev.set(Some(type_));
        }
    }

    fn escape_key(&mut self, key: &str) -> Result<(), Error> {
        let ok = !key.is_empty()
            && key.chars().all(|c| match c {
                'a'..='z' | 'A'..='Z' | '0'..='9' | '-' | '_' => true,
                _ => false,
            });
        if ok {
            write!(self.dst, "{}", key).map_err(ser::Error::custom)?;
        } else {
            self.emit_str(key)?;
        }
        Ok(())
    }

    fn emit_str(&mut self, value: &str) -> Result<(), Error> {
        self.dst.push('"');
        for ch in value.chars() {
            match ch {
                '\u{8}' => self.dst.push_str("\\b"),
                '\u{9}' => self.dst.push_str("\\t"),
                '\u{a}' => self.dst.push_str("\\n"),
                '\u{c}' => self.dst.push_str("\\f"),
                '\u{d}' => self.dst.push_str("\\r"),
                '\u{22}' => self.dst.push_str("\\\""),
                '\u{5c}' => self.dst.push_str("\\\\"),
                c if c <= '\u{1f}' || c == '\u{7f}' => {
                    write!(self.dst, "\\u{:04X}", ch as u32).map_err(ser::Error::custom)?;
                }
                ch => self.dst.push(ch),
            }
        }
        self.dst.push('"');
        Ok(())
    }

    fn emit_table_header(&mut self, state: &State) -> Result<(), Error> {
        let array_of_tables = match *state {
            State::End => return Ok(()),
            State::Array { .. } => true,
            State::Table { .. } => false,
        };

        // Unlike [..]s, we can't omit [[..]] ancestors, so be sure to emit
        // table headers for them.
        let mut p = state;
        if let State::Array { first, parent, .. } = *state {
            if first.get() {
                p = parent;
            }
        }
        while let State::Table { first, parent, .. } = *p {
            p = parent;
            if !first.get() {
                break;
            }
            if let State::Array {
                parent: &State::Table { .. },
                ..
            } = *parent
            {
                self.emit_table_header(parent)?;
                break;
            }
        }

        match *state {
            State::Table { first, .. } => {
                if !first.get() {
                    // Newline if we are a table that is not the first table in
                    // the document.
                    self.dst.push('\n');
                }
            }
            State::Array { parent, first, .. } => {
                if !first.get() {
                    // Always newline if we are not the first item in the
                    // table-array
                    self.dst.push('\n');
                } else if let State::Table { first, .. } = *parent {
                    if !first.get() {
                        // Newline if we are not the first item in the document
                        self.dst.push('\n');
                    }
                }
            }
            State::End => {}
        }
        self.dst.push('[');
        if array_of_tables {
            self.dst.push('[');
        }
        self.emit_key_part(state)?;
        if array_of_tables {
            self.dst.push(']');
        }
        self.dst.push_str("]\n");
        Ok(())
    }

    fn emit_key_part(&mut self, key: &State) -> Result<bool, Error> {
        match *key {
            State::Array { parent, .. } => self.emit_key_part(parent),
            State::End => Ok(true),
            State::Table {
                key,
                parent,
                table_emitted,
                ..
            } => {
                table_emitted.set(true);
                let first = self.emit_key_part(parent)?;
                if !first {
                    self.dst.push('.');
                }
                self.escape_key(key)?;
                Ok(false)
            }
        }
    }
}

macro_rules! serialize_float {
    ($this:expr, $v:expr) => {{
        $this.emit_key(ArrayState::Started)?;
        match ($v.is_sign_negative(), $v.is_nan(), $v == 0.0) {
            (true, true, _) => write!($this.dst, "-nan"),
            (false, true, _) => write!($this.dst, "nan"),
            (true, false, true) => write!($this.dst, "-0.0"),
            (false, false, true) => write!($this.dst, "0.0"),
            (_, false, false) => write!($this.dst, "{}", $v).and_then(|_| {
                if $v % 1.0 == 0.0 {
                    write!($this.dst, ".0")
                } else {
                    Ok(())
                }
            }),
        }
        .map_err(ser::Error::custom)?;

        if let State::Table { .. } = $this.state {
            $this.dst.push_str("\n");
        }
        return Ok(());
    }};
}

impl<'a, 'b> ser::Serializer for &'b mut Serializer<'a> {
    type Ok = ();
    type Error = Error;
    type SerializeSeq = SerializeSeq<'a, 'b>;
    type SerializeTuple = SerializeSeq<'a, 'b>;
    type SerializeTupleStruct = SerializeSeq<'a, 'b>;
    type SerializeTupleVariant = ser::Impossible<(), Error>;
    type SerializeMap = SerializeTable<'a, 'b>;
    type SerializeStruct = SerializeTable<'a, 'b>;
    type SerializeStructVariant = ser::Impossible<(), Error>;

    fn serialize_bool(self, v: bool) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_i8(self, v: i8) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_i16(self, v: i16) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_i32(self, v: i32) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_i64(self, v: i64) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_u8(self, v: u8) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_u16(self, v: u16) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_u32(self, v: u32) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_u64(self, v: u64) -> Result<(), Self::Error> {
        self.display(v, ArrayState::Started)
    }

    fn serialize_f32(self, v: f32) -> Result<(), Self::Error> {
        serialize_float!(self, v)
    }

    fn serialize_f64(self, v: f64) -> Result<(), Self::Error> {
        serialize_float!(self, v)
    }

    fn serialize_char(self, v: char) -> Result<(), Self::Error> {
        let mut buf = [0; 4];
        self.serialize_str(v.encode_utf8(&mut buf))
    }

    fn serialize_str(self, value: &str) -> Result<(), Self::Error> {
        self.emit_key(ArrayState::Started)?;
        self.emit_str(value)?;
        if let State::Table { .. } = self.state {
            self.dst.push('\n');
        }
        Ok(())
    }

    fn serialize_bytes(self, value: &[u8]) -> Result<(), Self::Error> {
        value.serialize(self)
    }

    fn serialize_none(self) -> Result<(), Self::Error> {
        Err(Error::UnsupportedNone)
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        value.serialize(self)
    }

    fn serialize_unit(self) -> Result<(), Self::Error> {
        Err(Error::UnsupportedType)
    }

    fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error> {
        Err(Error::UnsupportedType)
    }

    fn serialize_unit_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        variant: &'static str,
    ) -> Result<(), Self::Error> {
        self.serialize_str(variant)
    }

    fn serialize_newtype_struct<T: ?Sized>(
        self,
        _name: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(
        self,
        _name: &'static str,
        _variant_index: u32,
        _variant: &'static str,
        _value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        Err(Error::UnsupportedType)
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        self.array_type(ArrayState::Started);
        Ok(SerializeSeq {
            ser: self,
            first: Cell::new(true),
            type_: Cell::new(None),
            len,
        })
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_struct(
        self,
        _name: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        _variant: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
        Err(Error::UnsupportedType)
    }

    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        self.array_type(ArrayState::StartedAsATable);
        Ok(SerializeTable {
            ser: self,
            key: String::new(),
            first: Cell::new(true),
            table_emitted: Cell::new(false),
        })
    }

    fn serialize_struct(
        self,
        _name: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeStruct, Self::Error> {
        self.array_type(ArrayState::StartedAsATable);
        Ok(SerializeTable {
            ser: self,
            key: String::new(),
            first: Cell::new(true),
            table_emitted: Cell::new(false),
        })
    }

    fn serialize_struct_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        _variant: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeStructVariant, Self::Error> {
        Err(Error::UnsupportedType)
    }
}

impl<'a, 'b> ser::SerializeSeq for SerializeSeq<'a, 'b> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut Serializer {
            dst: &mut *self.ser.dst,
            state: State::Array {
                parent: &self.ser.state,
                first: &self.first,
                type_: &self.type_,
                len: self.len,
            },
        })?;
        self.first.set(false);
        Ok(())
    }

    fn end(self) -> Result<(), Error> {
        match self.type_.get() {
            Some(ArrayState::StartedAsATable) => return Ok(()),
            Some(ArrayState::Started) => self.ser.dst.push(']'),
            None => {
                assert!(self.first.get());
                self.ser.emit_key(ArrayState::Started)?;
                self.ser.dst.push_str("[]");
            }
        }
        if let State::Table { .. } = self.ser.state {
            self.ser.dst.push('\n');
        }
        Ok(())
    }
}

impl<'a, 'b> ser::SerializeTuple for SerializeSeq<'a, 'b> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        ser::SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> Result<(), Error> {
        ser::SerializeSeq::end(self)
    }
}

impl<'a, 'b> ser::SerializeTupleStruct for SerializeSeq<'a, 'b> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        ser::SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> Result<(), Error> {
        ser::SerializeSeq::end(self)
    }
}

impl<'a, 'b> ser::SerializeMap for SerializeTable<'a, 'b> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        self.key = input.serialize(StringExtractor)?;
        Ok(())
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        let res = value.serialize(&mut Serializer {
            dst: &mut *self.ser.dst,
            state: State::Table {
                key: &self.key,
                parent: &self.ser.state,
                first: &self.first,
                table_emitted: &self.table_emitted,
            },
        });
        match res {
            Ok(()) => self.first.set(false),
            Err(Error::UnsupportedNone) => {}
            Err(e) => return Err(e),
        }
        Ok(())
    }

    fn end(self) -> Result<(), Error> {
        if self.first.get() {
            let state = self.ser.state.clone();
            self.ser.emit_table_header(&state)?;
        }
        Ok(())
    }
}

impl<'a, 'b> ser::SerializeStruct for SerializeTable<'a, 'b> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        let res = value.serialize(&mut Serializer {
            dst: &mut *self.ser.dst,
            state: State::Table {
                key,
                parent: &self.ser.state,
                first: &self.first,
                table_emitted: &self.table_emitted,
            },
        });
        match res {
            Ok(()) => self.first.set(false),
            Err(Error::UnsupportedNone) => {}
            Err(e) => return Err(e),
        }
        Ok(())
    }

    fn end(self) -> Result<(), Error> {
        if self.first.get() {
            let state = self.ser.state.clone();
            self.ser.emit_table_header(&state)?;
        }
        Ok(())
    }
}

struct StringExtractor;

impl ser::Serializer for StringExtractor {
    type Ok = String;
    type Error = Error;
    type SerializeSeq = ser::Impossible<String, Error>;
    type SerializeTuple = ser::Impossible<String, Error>;
    type SerializeTupleStruct = ser::Impossible<String, Error>;
    type SerializeTupleVariant = ser::Impossible<String, Error>;
    type SerializeMap = ser::Impossible<String, Error>;
    type SerializeStruct = ser::Impossible<String, Error>;
    type SerializeStructVariant = ser::Impossible<String, Error>;

    fn serialize_bool(self, _v: bool) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_i8(self, _v: i8) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_i16(self, _v: i16) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_i32(self, _v: i32) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_i64(self, _v: i64) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_u8(self, _v: u8) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_u16(self, _v: u16) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_u32(self, _v: u32) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_u64(self, _v: u64) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_f32(self, _v: f32) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_f64(self, _v: f64) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_char(self, _v: char) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_str(self, value: &str) -> Result<String, Self::Error> {
        Ok(value.to_string())
    }

    fn serialize_bytes(self, _value: &[u8]) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_none(self) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<String, Self::Error>
    where
        T: Serialize,
    {
        Err(Error::KeyNotString)
    }

    fn serialize_unit(self) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_unit_struct(self, _name: &'static str) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_unit_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        _variant: &'static str,
    ) -> Result<String, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_newtype_struct<T: ?Sized>(
        self,
        _name: &'static str,
        value: &T,
    ) -> Result<String, Self::Error>
    where
        T: Serialize,
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(
        self,
        _name: &'static str,
        _variant_index: u32,
        _variant: &'static str,
        _value: &T,
    ) -> Result<String, Self::Error>
    where
        T: Serialize,
    {
        Err(Error::KeyNotString)
    }

    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_tuple_struct(
        self,
        _name: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_tuple_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        _variant: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_struct(
        self,
        _name: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeStruct, Self::Error> {
        Err(Error::KeyNotString)
    }

    fn serialize_struct_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        _variant: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeStructVariant, Self::Error> {
        Err(Error::KeyNotString)
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::UnsupportedType => "unsupported Rust type".fmt(f),
            Error::KeyNotString => "map key was not a string".fmt(f),
            Error::ValueAfterTable => "values must be emitted before tables".fmt(f),
            Error::UnsupportedNone => "unsupported None value".fmt(f),
            Error::Custom(ref s) => s.fmt(f),
        }
    }
}

impl error::Error for Error {}

impl ser::Error for Error {
    fn custom<T: Display>(msg: T) -> Error {
        Error::Custom(msg.to_string())
    }
}

[ Dauer der Verarbeitung: 0.32 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge