Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  ref_serializer.rs

  Sprache: Rust
 

use std::borrow::BorrowMut;

use crate::{serializer::Serializer, KeyRef, RefBareItem};
#[cfg(feature = "parsed-types")]
use crate::{Item, ListEntry};

/// Serializes `Item` field value components incrementally.
///
/// Note: The serialization conforms to [RFC 9651], meaning that
/// [`Dates`][crate::Date] and [`Display Strings`][RefBareItem::DisplayString],
/// which cause parsing errors under [RFC 8941], will be serialized
/// unconditionally. The consumer of this API is responsible for determining
/// whether it is valid to serialize these bare items for any specific field.
///
/// [RFC 8941]: <https://httpwg.org/specs/rfc8941.html>
/// [RFC 9651]: <https://httpwg.org/specs/rfc9651.html>
/// ```
/// use sfv::{KeyRef, ItemSerializer};
///
/// # fn main() -> Result<(), sfv::Error> {
/// let serialized_item = ItemSerializer::new()
///     .bare_item(11)
///     .parameter(KeyRef::from_str("foo")?, true)
///     .finish();
///
/// assert_eq!(serialized_item, "11;foo");
/// # Ok(())
/// # }
/// ```
// https://httpwg.org/specs/rfc9651.html#ser-item
#[derive(Debug)]
#[must_use]
pub struct ItemSerializer<W> {
    buffer: W,
}

impl Default for ItemSerializer<String> {
    fn default() -> Self {
        Self::new()
    }
}

impl ItemSerializer<String> {
    /// Creates a serializer that writes into a new string.
    pub fn new() -> Self {
        Self {
            buffer: String::new(),
        }
    }
}

impl<'a> ItemSerializer<&'mut String> {
    /// Creates a serializer that writes into the given string.
    pub fn with_buffer(buffer: &'a mut String) -> Self {
        Self { buffer }
    }
}

impl<W: BorrowMut<String>> ItemSerializer<W> {
    /// Serializes the given bare item.
    ///
    /// Returns a serializer for the item's parameters.
    pub fn bare_item<'b>(
        mut self,
        bare_item: impl Into<RefBareItem<'b>>,
    ) -> ParameterSerializer<W> {
        Serializer::serialize_bare_item(bare_item, self.buffer.borrow_mut());
        ParameterSerializer {
            buffer: self.buffer,
        }
    }
}

/// Serializes parameters incrementally.
#[derive(Debug)]
#[must_use]
pub struct ParameterSerializer<W> {
    buffer: W,
}

impl<W: BorrowMut<String>> ParameterSerializer<W> {
    /// Serializes a parameter with the given name and value.
    ///
    /// Returns the serializer.
    pub fn parameter<'b>(mut self, name: &KeyRef, value: impl Into<RefBareItem<'b>>) -> Self {
        Serializer::serialize_parameter(name, value, self.buffer.borrow_mut());
        self
    }

    /// Serializes the given parameters.
    ///
    /// Returns the serializer.
    pub fn parameters<'b>(
        mut self,
        params: impl IntoIterator<Item = (impl AsRef<KeyRef>, impl Into<RefBareItem<'b>>)>,
    ) -> Self {
        for (name, value) in params {
            Serializer::serialize_parameter(name.as_ref(), value, self.buffer.borrow_mut());
        }
        self
    }

    /// Finishes parameter serialization and returns the serializer's output.
    #[must_use]
    pub fn finish(self) -> W {
        self.buffer
    }
}

fn maybe_write_separator(buffer: &mut String, first: &='color:red'>mut bool) {
    if *first {
        *first = false;
    } else {
        buffer.push_str(", ");
    }
}

/// Serializes `List` field value components incrementally.
///
/// Note: The serialization conforms to [RFC 9651], meaning that
/// [`Dates`][crate::Date] and [`Display Strings`][RefBareItem::DisplayString],
/// which cause parsing errors under [RFC 8941], will be serialized
/// unconditionally. The consumer of this API is responsible for determining
/// whether it is valid to serialize these bare items for any specific field.
///
/// [RFC 8941]: <https://httpwg.org/specs/rfc8941.html>
/// [RFC 9651]: <https://httpwg.org/specs/rfc9651.html>
/// ```
/// use sfv::{KeyRef, StringRef, TokenRef, ListSerializer};
///
/// # fn main() -> Result<(), sfv::Error> {
/// let mut ser = ListSerializer::new();
///
/// ser.bare_item(11)
///     .parameter(KeyRef::from_str("foo")?, true);
///
/// {
///     let mut ser = ser.inner_list();
///
///     ser.bare_item(TokenRef::from_str("abc")?)
///         .parameter(KeyRef::from_str("abc_param")?, false);
///
///     ser.bare_item(TokenRef::from_str("def")?);
///
///     ser.finish()
///         .parameter(KeyRef::from_str("bar")?, StringRef::from_str("val")?);
/// }
///
/// assert_eq!(
///     ser.finish().as_deref(),
///     Some(r#"11;foo, (abc;abc_param=?0 def);bar="val""#),
/// );
/// # Ok(())
/// # }
/// ```
// https://httpwg.org/specs/rfc9651.html#ser-list
#[derive(Debug)]
#[must_use]
pub struct ListSerializer<W> {
    buffer: W,
    first: bool,
}

impl Default for ListSerializer<String> {
    fn default() -> Self {
        Self::new()
    }
}

impl ListSerializer<String> {
    /// Creates a serializer that writes into a new string.
    pub fn new() -> Self {
        Self {
            buffer: String::new(),
            first: true,
        }
    }
}

impl<'a> ListSerializer<&'mut String> {
    /// Creates a serializer that writes into the given string.
    pub fn with_buffer(buffer: &'a mut String) -> Self {
        Self {
            buffer,
            first: true,
        }
    }
}

impl<W: BorrowMut<String>> ListSerializer<W> {
    /// Serializes the given bare item as a member of the list.
    ///
    /// Returns a serializer for the item's parameters.
    pub fn bare_item<'b>(
        &mut self,
        bare_item: impl Into<RefBareItem<'b>>,
    ) -> ParameterSerializer<&mut String> {
        let buffer = self.buffer.borrow_mut();
        maybe_write_separator(buffer, &mut self.first);
        Serializer::serialize_bare_item(bare_item, buffer);
        ParameterSerializer { buffer }
    }

    /// Opens an inner list, returning a serializer to be used for its items and
    /// parameters.
    pub fn inner_list(&mut self) -> InnerListSerializer {
        let buffer = self.buffer.borrow_mut();
        maybe_write_separator(buffer, &mut self.first);
        buffer.push('(');
        InnerListSerializer {
            buffer: Some(buffer),
        }
    }

    /// Serializes the given members of the list.
    #[cfg(feature = "parsed-types")]
    pub fn members<'b>(&mut self, members: impl IntoIterator<Item = &'b ListEntry>) {
        for value in members {
            match value {
                ListEntry::Item(value) => {
                    _ = self.bare_item(&value.bare_item).parameters(&value.params);
                }
                ListEntry::InnerList(value) => {
                    let mut ser = self.inner_list();
                    ser.items(&value.items);
                    _ = ser.finish().parameters(&value.params);
                }
            }
        }
    }

    /// Finishes serialization of the list and returns the underlying output.
    ///
    /// Returns `None` if and only if no members were serialized, as [empty
    /// lists are not meant to be serialized at
    /// all](https://httpwg.org/specs/rfc9651.html#text-serialize).
    #[must_use]
    pub fn finish(self) -> Option<W> {
        if self.first {
            None
        } else {
            Some(self.buffer)
        }
    }
}

/// Serializes `Dictionary` field value components incrementally.
///
/// Note: The serialization conforms to [RFC 9651], meaning that
/// [`Dates`][crate::Date] and [`Display Strings`][RefBareItem::DisplayString],
/// which cause parsing errors under [RFC 8941], will be serialized
/// unconditionally. The consumer of this API is responsible for determining
/// whether it is valid to serialize these bare items for any specific field.
///
/// [RFC 8941]: <https://httpwg.org/specs/rfc8941.html>
/// [RFC 9651]: <https://httpwg.org/specs/rfc9651.html>
///
/// ```
/// use sfv::{KeyRef, StringRef, TokenRef, DictSerializer, Decimal};
///
/// # fn main() -> Result<(), sfv::Error> {
/// let mut ser = DictSerializer::new();
///
/// ser.bare_item(KeyRef::from_str("member1")?, 11)
///     .parameter(KeyRef::from_str("foo")?, true);
///
/// {
///   let mut ser = ser.inner_list(KeyRef::from_str("member2")?);
///
///   ser.bare_item(TokenRef::from_str("abc")?)
///       .parameter(KeyRef::from_str("abc_param")?, false);
///
///   ser.bare_item(TokenRef::from_str("def")?);
///
///   ser.finish()
///      .parameter(KeyRef::from_str("bar")?, StringRef::from_str("val")?);
/// }
///
/// ser.bare_item(KeyRef::from_str("member3")?, Decimal::try_from(12.34566)?);
///
/// assert_eq!(
///     ser.finish().as_deref(),
///     Some(r#"member1=11;foo, member2=(abc;abc_param=?0 def);bar="val", member3=12.346"#),
/// );
/// # Ok(())
/// # }
/// ```
// https://httpwg.org/specs/rfc9651.html#ser-dictionary
#[derive(Debug)]
#[must_use]
pub struct DictSerializer<W> {
    buffer: W,
    first: bool,
}

impl Default for DictSerializer<String> {
    fn default() -> Self {
        Self::new()
    }
}

impl DictSerializer<String> {
    /// Creates a serializer that writes into a new string.
    pub fn new() -> Self {
        Self {
            buffer: String::new(),
            first: true,
        }
    }
}

impl<'a> DictSerializer<&'mut String> {
    /// Creates a serializer that writes into the given string.
    pub fn with_buffer(buffer: &'a mut String) -> Self {
        Self {
            buffer,
            first: true,
        }
    }
}

impl<W: BorrowMut<String>> DictSerializer<W> {
    /// Serializes the given bare item as a member of the dictionary with the
    /// given key.
    ///
    /// Returns a serializer for the item's parameters.
    pub fn bare_item<'b>(
        &mut self,
        name: &KeyRef,
        value: impl Into<RefBareItem<'b>>,
    ) -> ParameterSerializer<&mut String> {
        let buffer = self.buffer.borrow_mut();
        maybe_write_separator(buffer, &mut self.first);
        Serializer::serialize_key(name, buffer);
        let value = value.into();
        if value != RefBareItem::Boolean(true) {
            buffer.push('=');
            Serializer::serialize_bare_item(value, buffer);
        }
        ParameterSerializer { buffer }
    }

    /// Opens an inner list with the given key, returning a serializer to be
    /// used for its items and parameters.
    pub fn inner_list(&mut self, name: &KeyRef) -> InnerListSerializer {
        let buffer = self.buffer.borrow_mut();
        maybe_write_separator(buffer, &mut self.first);
        Serializer::serialize_key(name, buffer);
        buffer.push_str("=(");
        InnerListSerializer {
            buffer: Some(buffer),
        }
    }

    /// Serializes the given members of the dictionary.
    #[cfg(feature = "parsed-types")]
    pub fn members<'b>(
        &mut self,
        members: impl IntoIterator<Item = (impl AsRef<KeyRef>, &'b ListEntry)>,
    ) {
        for (name, value) in members {
            match value {
                ListEntry::Item(value) => {
                    _ = self
                        .bare_item(name.as_ref(), &value.bare_item)
                        .parameters(&value.params);
                }
                ListEntry::InnerList(value) => {
                    let mut ser = self.inner_list(name.as_ref());
                    ser.items(&value.items);
                    _ = ser.finish().parameters(&value.params);
                }
            }
        }
    }

    /// Finishes serialization of the dictionary and returns the underlying output.
    ///
    /// Returns `None` if and only if no members were serialized, as [empty
    /// dictionaries are not meant to be serialized at
    /// all](https://httpwg.org/specs/rfc9651.html#text-serialize).
    #[must_use]
    pub fn finish(self) -> Option<W> {
        if self.first {
            None
        } else {
            Some(self.buffer)
        }
    }
}

/// Serializes inner lists incrementally.
///
/// The inner list will be closed automatically when the serializer is dropped.
/// To set the inner list's parameters, call [`InnerListSerializer::finish`].
///
/// Failing to drop the serializer or call its `finish` method will result in
/// an invalid serialization that lacks a closing `)` character.
// https://httpwg.org/specs/rfc9651.html#ser-innerlist
#[derive(Debug)]
#[must_use]
pub struct InnerListSerializer<'a> {
    buffer: Option<&'a mut String>,
}

impl Drop for InnerListSerializer<'_> {
    fn drop(&mut self) {
        if let Some(ref mut buffer) = self.buffer {
            buffer.push(')');
        }
    }
}

impl<'a> InnerListSerializer<'a> {
    /// Serializes the given bare item as a member of the inner list.
    ///
    /// Returns a serializer for the item's parameters.
    #[allow(clippy::missing_panics_doc)] // The unwrap is safe by construction.
    pub fn bare_item<'b>(
        &mut self,
        bare_item: impl Into<RefBareItem<'b>>,
    ) -> ParameterSerializer<&mut String> {
        let buffer = self.buffer.as_mut().unwrap();
        if !buffer.is_empty() && !buffer.ends_with('(') {
            buffer.push(' ');
        }
        Serializer::serialize_bare_item(bare_item, buffer);
        ParameterSerializer { buffer }
    }

    /// Serializes the given items as members of the inner list.
    #[cfg(feature = "parsed-types")]
    pub fn items<'b>(&mut self, items: impl IntoIterator<Item = &'b Item>) {
        for item in items {
            _ = self.bare_item(&item.bare_item).parameters(&item.params);
        }
    }

    /// Closes the inner list and returns a serializer for its parameters.
    #[allow(clippy::missing_panics_doc)]
    pub fn finish(mut self) -> ParameterSerializer<&'a mut String> {
        let buffer = self.buffer.take().unwrap();
        buffer.push(')');
        ParameterSerializer { buffer }
    }
}

Messung V0.5 in Prozent
C=91 H=97 G=93

¤ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© 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