modi 0.1.1

An out-of-the-box modular dependency injection web application framework.
Documentation
use std::{ fmt::Display, path::PathBuf, str::FromStr };

use semver::Version;
use serde::{ Deserialize, Serialize };

use super::Interface;

pub trait FullManifest: Interface {
    fn full_manifest(&self) -> Manifest;
}
impl<T: ?Sized + Interface> FullManifest for T {
    fn full_manifest(&self) -> Manifest {
        let depends: Vec<String> = self
            .depends()
            .iter()
            .map(|m| m.name().to_owned())
            .collect();
        let mut manifest = self.manifest();
        manifest.set_depends(depends);
        manifest
    }
}

/// A module manifest.
#[derive(Debug, Serialize, Deserialize, getset2::WithSetters, getset2::Getters)]
#[getset(set_with = "pub", get = "pub")]
pub struct Manifest {
    ///  name
    name: String,
    /// Short summary of the 's purpose
    summary: String,
    /// Long description of the 's purpose
    description: String,
    /// Author
    author: String,
    ///  home page
    homepage: String,
    /// Category
    category: Category,
    /// Version
    version: Version,
    /// Data files always loaded
    data: Vec<PathBuf>,
    /// Data files only loaded in demonstration mode
    demo: Vec<PathBuf>,
    #[getset(skip)]
    depends: Vec<String>,
}
impl Manifest {
    pub fn to_string_pretty(&self) -> String {
        let mut writer = String::new();
        let mut ser = quick_xml::se::Serializer::new(&mut writer);
        ser.indent(' ', 2);
        self.serialize(ser).unwrap();
        writer
    }
    pub fn set_depends(&mut self, depends: Vec<String>) {
        self.depends = depends;
    }
}
impl Default for Manifest {
    fn default() -> Self {
        Self {
            name: Default::default(),
            summary: Default::default(),
            description: Default::default(),
            author: Default::default(),
            homepage: Default::default(),
            category: Default::default(),
            version: Version::new(0, 1, 0),
            data: Default::default(),
            demo: Default::default(),
            depends: Default::default(),
        }
    }
}

impl Display for Manifest {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", quick_xml::se::to_string(self).map_err(|_| std::fmt::Error)?)
    }
}

impl FromStr for Manifest {
    type Err = quick_xml::DeError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        quick_xml::de::from_str(s)
    }
}

#[derive(Debug, Serialize, Deserialize, strum::Display)]
pub enum Category {
    Uncategorized,
}
impl Default for Category {
    fn default() -> Self {
        Category::Uncategorized
    }
}

#[test]
fn demo() {
    let manifest = Manifest {
        name: "_name".to_string(), // Replace with actual  name
        summary: "Short (1 phrase/line) summary of the 's purpose".to_string(),
        description: "Long description of 's purpose".to_string(),
        author: "My Company".to_string(),
        homepage: "https://www.yourcompany.com".to_string(),
        category: Category::Uncategorized,
        version: "0.1.0".parse().unwrap(),
        data: vec!["views/views.xml".into(), "views/templates.xml".into()],
        demo: vec!["demo/demo.xml".into()],
        depends: vec![],
    };

    println!("{}", manifest);
    println!("{}", manifest.to_string_pretty());
}