pnets_pnml 0.1.0

A parser for PNML Petri net format
Documentation
use serde::{Deserialize, Serialize, Serializer};

pub type Decimal = f64;
pub type Color = String;
#[derive(Deserialize)]
pub struct PositiveDecimal(pub f64);

impl Serialize for PositiveDecimal {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        use serde::ser::Error;
        if self.0 > 999.9 {
            Err(S::Error::custom("Value must be less than 1000"))
        } else if self.0 < 0.0 {
            Err(S::Error::custom("Value must be positive"))
        } else {
            serializer.serialize_str(&format!("{:.1}", self.0))
        }
    }
}

#[derive(Serialize, Deserialize, Default)]
pub struct NotNul {
    #[serde(rename = "$value")]
    pub value: usize,
}

#[derive(Serialize, Deserialize)]
pub struct PositiveInteger {
    #[serde(rename = "$value")]
    value: usize,
}

#[derive(Serialize, Deserialize)]
pub struct SimpleText {
    #[serde(rename = "$value")]
    pub text: String,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "position")]
pub struct Position {
    pub x: Decimal,
    pub y: Decimal,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "offset")]
pub struct Offset {
    pub x: Decimal,
    pub y: Decimal,
}

#[derive(Deserialize)]
pub enum Shape {
    #[serde(rename = "line")]
    Line,
    #[serde(rename = "curve")]
    Curve,
}

impl Serialize for Shape {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(match self {
            Self::Line => "line",
            Self::Curve => "curve",
        })
    }
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "line")]
pub struct Line {
    pub shape: Option<Shape>,
    pub color: Option<Color>,
    pub width: Option<PositiveDecimal>,
}

#[derive(Deserialize)]
pub enum Rotation {
    #[serde(rename = "vertical")]
    Vertical,
    #[serde(rename = "horizontal")]
    Horizontal,
    #[serde(rename = "diagonal")]
    Diagonal,
}

impl Serialize for Rotation {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(match self {
            Rotation::Vertical => "vertical",
            Rotation::Horizontal => "horizontal",
            Rotation::Diagonal => "diagonal",
        })
    }
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "fill")]
pub struct Fill {
    pub color: Option<Color>,
    #[serde(rename = "gradient-color")]
    pub gradient_color: Option<Color>,
    #[serde(rename = "gradient-rotation")]
    pub gradient_rotation: Option<Rotation>,
    pub image: String,
}

#[derive(Deserialize)]
pub enum Decoration {
    #[serde(rename = "underline")]
    Underline,
    #[serde(rename = "overline")]
    Overline,
    #[serde(rename = "line-through")]
    LineThrough,
}

impl Serialize for Decoration {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(match self {
            Decoration::Underline => "underline",
            Decoration::Overline => "overline",
            Decoration::LineThrough => "line-through",
        })
    }
}

#[derive(Deserialize)]
pub enum Align {
    #[serde(rename = "left")]
    Left,
    #[serde(rename = "center")]
    Center,
    #[serde(rename = "right")]
    Right,
}

impl Serialize for Align {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(match self {
            Align::Left => "left",
            Align::Center => "center",
            Align::Right => "right",
        })
    }
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "font")]
pub struct Font {
    pub family: Option<String>,
    pub style: Option<String>,
    pub weight: Option<String>,
    pub size: Option<String>,
    pub decoration: Option<Decoration>,
    pub align: Option<Align>,
    pub rotation: Option<Decimal>,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "graphics")]
pub struct AnnotationGraphics {
    pub offset: Offset,
    pub fill: Option<Fill>,
    pub font: Option<Font>,
    pub line: Option<Line>,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "graphics")]
pub struct EdgeGraphics {
    #[serde(rename = "position", default)]
    positions: Vec<Position>,
    line: Option<Line>,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "graphics")]
pub struct NodeGraphics {
    pub position: Position,
    pub dimension: Option<Dimension>,
    pub fill: Option<Fill>,
    pub line: Option<Line>,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "dimension")]
pub struct Dimension {
    pub x: PositiveDecimal,
    pub y: PositiveDecimal,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "name")]
pub struct Name {
    pub text: SimpleText,
    pub graphics: Option<AnnotationGraphics>,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "referencePlace")]
pub struct PlaceReference {
    pub id: String,
    #[serde(rename = "ref")]
    pub ref_: String,
    pub name: Option<Name>,
    pub graphics: Option<NodeGraphics>,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "referencePlace")]
pub struct TransitionReference {
    pub id: String,
    #[serde(rename = "ref")]
    pub ref_: String,
    pub name: Option<Name>,
    pub graphics: Option<NodeGraphics>,
}

#[derive(Serialize, Deserialize, Default)]
#[serde(rename = "page")]
pub struct Page<Place, Transition, Arc> {
    pub id: String,
    #[serde(rename = "page", default)]
    pub pages: Vec<Page<Place, Transition, Arc>>,
    #[serde(rename = "place", default)]
    pub places: Vec<Place>,
    #[serde(rename = "transition", default)]
    pub transitions: Vec<Transition>,
    #[serde(rename = "referencePlace", default)]
    pub place_references: Vec<PlaceReference>,
    #[serde(rename = "referenceTransition", default)]
    pub transition_references: Vec<TransitionReference>,
    #[serde(rename = "arc", default)]
    pub arcs: Vec<Arc>,
}

#[derive(Serialize, Deserialize, Default)]
#[serde(rename = "net")]
pub struct Net<Place: Default, Transition: Default, Arc: Default> {
    pub id: String,
    #[serde(rename = "type")]
    pub type_: String,
    pub name: Option<Name>,
    #[serde(rename = "page")]
    pub pages: Vec<Page<Place, Transition, Arc>>,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "pnml")]
pub struct Pnml<Net> {
    pub xmlns: String,
    #[serde(rename = "net")]
    pub nets: Vec<Net>,
}