Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  key.rs

  Sprache: Rust
 

use crate::se::SeError;
use serde::ser::{Impossible, Serialize, Serializer};
use serde::serde_if_integer128;
use std::fmt::Write;

/// A serializer, that ensures, that only plain types can be serialized,
/// so result can be used as an XML tag or attribute name.
///
/// This serializer does not check that name does not contain characters that
/// [not allowed] in XML names, because in some cases it should pass names
/// that would be filtered on higher level.
///
/// [not allowed]: https://www.w3.org/TR/xml11/#sec-common-syn
pub struct QNameSerializer<W: Write> {
    /// Writer to which this serializer writes content
    pub writer: W,
}

impl<W: Write> QNameSerializer<W> {
    #[inline]
    fn write_str(&mut self, value: &str) -> Result<(), SeError> {
        Ok(self.writer.write_str(value)?)
    }
}

impl<W: Write> Serializer for QNameSerializer<W> {
    type Ok = W;
    type Error = SeError;

    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
    type SerializeMap = Impossible<Self::Ok, Self::Error>;
    type SerializeStruct = Impossible<Self::Ok, Self::Error>;
    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;

    write_primitive!();

    fn serialize_str(mut self, value: &str) -> Result<Self::Ok, Self::Error> {
        self.write_str(value)?;
        Ok(self.writer)
    }

    /// Because unit type can be represented only by empty string which is not
    /// a valid XML name, serialization of unit returns `Err(Unsupported)`
    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
        Err(SeError::Unsupported(
            "cannot serialize unit type `()` as an XML tag name".into(),
        ))
    }

    /// Because unit struct can be represented only by empty string which is not
    /// a valid XML name, serialization of unit struct returns `Err(Unsupported)`
    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
        Err(SeError::Unsupported(
            format!("cannot serialize unit struct `{}` as an XML tag name", name).into(),
        ))
    }

    /// We cannot store both a variant discriminant and a variant value,
    /// so serialization of enum newtype variant returns `Err(Unsupported)`
    fn serialize_newtype_variant<T: ?Sized + Serialize>(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        _value: &T,
    ) -> Result<Self::Ok, SeError> {
        Err(SeError::Unsupported(
            format!(
                "cannot serialize enum newtype variant `{}::{}` as an XML tag name",
                name, variant
            )
            .into(),
        ))
    }

    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        Err(SeError::Unsupported(
            "cannot serialize sequence as an XML tag name".into(),
        ))
    }

    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        Err(SeError::Unsupported(
            "cannot serialize tuple as an XML tag name".into(),
        ))
    }

    fn serialize_tuple_struct(
        self,
        name: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
        Err(SeError::Unsupported(
            format!(
                "cannot serialize tuple struct `{}` as an XML tag name",
                name
            )
            .into(),
        ))
    }

    fn serialize_tuple_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
        Err(SeError::Unsupported(
            format!(
                "cannot serialize enum tuple variant `{}::{}` as an XML tag name",
                name, variant
            )
            .into(),
        ))
    }

    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        Err(SeError::Unsupported(
            "cannot serialize map as an XML tag name".into(),
        ))
    }

    fn serialize_struct(
        self,
        name: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeStruct, Self::Error> {
        Err(SeError::Unsupported(
            format!("cannot serialize struct `{}` as an XML tag name", name).into(),
        ))
    }

    fn serialize_struct_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        _len: usize,
    ) -> Result<Self::SerializeStructVariant, Self::Error> {
        Err(SeError::Unsupported(
            format!(
                "cannot serialize enum struct variant `{}::{}` as an XML tag name",
                name, variant
            )
            .into(),
        ))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::utils::Bytes;
    use pretty_assertions::assert_eq;
    use serde::Serialize;
    use std::collections::BTreeMap;

    #[derive(Debug, Serialize, PartialEq)]
    struct Unit;

    #[derive(Debug, Serialize, PartialEq)]
    struct Newtype(bool);

    #[derive(Debug, Serialize, PartialEq)]
    struct Tuple(&'static str, usize);

    #[derive(Debug, Serialize, PartialEq)]
    struct Struct {
        key: &'static str,
        val: usize,
    }

    #[derive(Debug, Serialize, PartialEq)]
    enum Enum {
        Unit,
        #[serde(rename = "<\"&'>")]
        UnitEscaped,
        Newtype(bool),
        Tuple(&'static str, usize),
        Struct {
            key: &'static str,
            val: usize,
        },
    }

    /// Checks that given `$data` successfully serialized as `$expected`
    macro_rules! serialize_as {
        ($name:ident: $data:expr => $expected:literal) => {
            #[test]
            fn $name() {
                let ser = QNameSerializer {
                    writer: String::new(),
                };

                let buffer = $data.serialize(ser).unwrap();
                assert_eq!(buffer, $expected);
            }
        };
    }

    /// Checks that attempt to serialize given `$data` results to a
    /// serialization error `$kind` with `$reason`
    macro_rules! err {
        ($name:ident: $data:expr => $kind:ident($reason:literal)) => {
            #[test]
            fn $name() {
                let mut buffer = String::new();
                let ser = QNameSerializer {
                    writer: &mut buffer,
                };

                match $data.serialize(ser).unwrap_err() {
                    SeError::$kind(e) => assert_eq!(e, $reason),
                    e => panic!(
                        "Expected `Err({}({}))`, but got `{:?}`",
                        stringify!($kind),
                        $reason,
                        e
                    ),
                }
                assert_eq!(buffer, "");
            }
        };
    }

    serialize_as!(false_: false => "false");
    serialize_as!(true_:  true  => "true");

    serialize_as!(i8_:    -42i8                => "-42");
    serialize_as!(i16_:   -4200i16             => "-4200");
    serialize_as!(i32_:   -42000000i32         => "-42000000");
    serialize_as!(i64_:   -42000000000000i64   => "-42000000000000");
    serialize_as!(isize_: -42000000000000isize => "-42000000000000");

    serialize_as!(u8_:    42u8                => "42");
    serialize_as!(u16_:   4200u16             => "4200");
    serialize_as!(u32_:   42000000u32         => "42000000");
    serialize_as!(u64_:   42000000000000u64   => "42000000000000");
    serialize_as!(usize_: 42000000000000usize => "42000000000000");

    serde_if_integer128! {
        serialize_as!(i128_: -420000000000000000000000000000i128 => "-420000000000000000000000000000");
        serialize_as!(u128_:  420000000000000000000000000000u128 => "420000000000000000000000000000");
    }

    serialize_as!(f32_: 4.2f32 => "4.2");
    serialize_as!(f64_: 4.2f64 => "4.2");

    serialize_as!(char_non_escaped: 'h' => "h");
    serialize_as!(char_lt:   '<' => "<");
    serialize_as!(char_gt:   '>' => ">");
    serialize_as!(char_amp:  '&' => "&");
    serialize_as!(char_apos: '\'' => "'");
    serialize_as!(char_quot: '"' => "\"");

    serialize_as!(str_valid_name: "valid-name" => "valid-name");
    serialize_as!(str_space: "string with spaces" => "string with spaces");
    serialize_as!(str_lt:   "string<" => "string<");
    serialize_as!(str_gt:   "string>" => "string>");
    serialize_as!(str_amp:  "string&" => "string&");
    serialize_as!(str_apos: "string'" => "string'");
    serialize_as!(str_quot: "string\"" => "string\"");

    err!(bytes: Bytes(b"<\"escaped & bytes'>")
        => Unsupported("`serialize_bytes` not supported yet"));

    serialize_as!(option_none: Option::<&str>::None => "");
    serialize_as!(option_some: Some("non-escaped-string") => "non-escaped-string");

    err!(unit: ()
        => Unsupported("cannot serialize unit type `()` as an XML tag name"));
    err!(unit_struct: Unit
        => Unsupported("cannot serialize unit struct `Unit` as an XML tag name"));

    serialize_as!(enum_unit: Enum::Unit => "Unit");
    serialize_as!(enum_unit_escaped: Enum::UnitEscaped => "<\"&'>");

    serialize_as!(newtype: Newtype(true) => "true");
    err!(enum_newtype: Enum::Newtype(false)
        => Unsupported("cannot serialize enum newtype variant `Enum::Newtype` as an XML tag name"));

    err!(seq: vec![123]
        => Unsupported("cannot serialize sequence as an XML tag name"));
    err!(tuple: ("<\"&'>", "with\t\r\n spaces", 3usize)
        => Unsupported("cannot serialize tuple as an XML tag name"));
    err!(tuple_struct: Tuple("first"42)
        => Unsupported("cannot serialize tuple struct `Tuple` as an XML tag name"));
    err!(enum_tuple: Enum::Tuple("first"42)
        => Unsupported("cannot serialize enum tuple variant `Enum::Tuple` as an XML tag name"));

    err!(map: BTreeMap::from([("_1"2), ("_3"4)])
        => Unsupported("cannot serialize map as an XML tag name"));
    err!(struct_: Struct { key: "answer", val: 42 }
        => Unsupported("cannot serialize struct `Struct` as an XML tag name"));
    err!(enum_struct: Enum::Struct { key: "answer", val: 42 }
        => Unsupported("cannot serialize enum struct variant `Enum::Struct` as an XML tag name"));
}

Messung V0.5 in Prozent
C=98 H=100 G=98

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002