Skip to main content

ed_journals/modules/ship/models/ship_module/
ship_kit_module.rs

1use std::num::ParseIntError;
2use std::str::FromStr;
3
4use lazy_static::lazy_static;
5use regex::Regex;
6use serde::Serialize;
7use thiserror::Error;
8
9use crate::from_str_deserialize_impl;
10use crate::modules::ship::{ShipType, ShipTypeError};
11
12#[derive(Debug, Serialize, Clone, PartialEq)]
13pub struct ShipKitModule {
14    pub ship: ShipType,
15    pub name: String,
16    pub piece: String,
17}
18
19#[derive(Debug, Error)]
20pub enum ShipKitModuleError {
21    #[error("Failed to parse ship kit number: {0}")]
22    FailedToParseShipKitNr(#[from] ParseIntError),
23
24    #[error(transparent)]
25    ShipTypeError(#[from] ShipTypeError),
26
27    #[error("Failed to parse ship kit module: '{0}'")]
28    FailedToParse(String),
29}
30
31lazy_static! {
32    static ref SHIP_KIT_MODULE_REGEX: Regex =
33        Regex::new(r#"^([a-z0-9_]+?)_shipkit([a-z0-9]+)_([a-z0-9]+)$"#).unwrap();
34}
35
36impl FromStr for ShipKitModule {
37    type Err = ShipKitModuleError;
38
39    fn from_str(s: &str) -> Result<Self, Self::Err> {
40        let Some(captures) = SHIP_KIT_MODULE_REGEX.captures(s) else {
41            return Err(ShipKitModuleError::FailedToParse(s.to_string()));
42        };
43
44        let ship = captures
45            .get(1)
46            .expect("Should have been captured already")
47            .as_str()
48            .parse()?;
49
50        let name = captures
51            .get(2)
52            .expect("Should have been captured already")
53            .as_str()
54            .to_string();
55
56        let piece = captures
57            .get(3)
58            .expect("Should have been captured already")
59            .as_str()
60            .to_string();
61
62        Ok(ShipKitModule { ship, name, piece })
63    }
64}
65
66from_str_deserialize_impl!(ShipKitModule);