1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use super::{TextName, ID};
use serde::{Deserialize, Serialize};
use std::convert::TryInto;

/// A data structure containing information on a single user on the system.
///
#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Operator<'a> {
    /// Unique user ID, which cannot be zero.
    operator_id: ID,
    //
    /// Name of the user.
    #[serde(borrow)]
    operator_name: Option<TextName<'a>>,
}

impl<'a> Operator<'a> {
    /// Get the operator ID.
    ///
    /// # Examples
    ///
    /// ~~~
    /// # use ichen_openprotocol::*;
    /// let opr = Operator::new(ID::from_u32(12345));
    /// assert_eq!(12345, opr.id());
    /// ~~~
    pub fn id(&self) -> ID {
        self.operator_id
    }

    // Get the operator's name, if any.
    ///
    /// # Examples
    ///
    /// ~~~
    /// # use ichen_openprotocol::*;
    /// # fn main() -> std::result::Result<(), String> {
    /// let opr = Operator::try_new_with_name(ID::from_u32(12345), "John")?;
    /// assert_eq!(Some("John"), opr.name());
    /// # Ok(())
    /// # }
    /// ~~~
    pub fn name(&self) -> Option<&str> {
        self.operator_name.as_ref().map(|name| name.as_ref())
    }

    /// Create an `Operator` with just an ID and no name.
    ///
    /// # Examples
    ///
    /// ~~~
    /// # use ichen_openprotocol::*;
    /// let opr = Operator::new(ID::from_u32(12345));
    /// assert_eq!(12345, opr.id());
    /// assert_eq!(None, opr.name());
    /// ~~~
    pub fn new(id: ID) -> Self {
        Self { operator_id: id, operator_name: None }
    }

    /// Create an `Operator` with ID and name.
    ///
    ///
    /// # Errors
    ///
    /// Returns `Err(`[`OpenProtocolError::EmptyField`]`)` if the `operator_name` field is
    /// set to an empty string or is all whitespace.
    ///
    /// ## Error Examples
    ///
    /// ~~~
    /// # use ichen_openprotocol::*;
    /// let result = Operator::try_new_with_name(ID::from_u32(12345), "");
    /// assert_eq!(Err("invalid value: a non-empty, non-whitespace string required for operator name".into()), result);
    /// ~~~
    ///
    /// # Examples
    ///
    /// ~~~
    /// # use ichen_openprotocol::*;
    /// # fn main() -> std::result::Result<(), String> {
    /// let opr = Operator::try_new_with_name(ID::from_u32(12345), "John")?;
    /// assert_eq!(12345, opr.id());
    /// assert_eq!(Some("John"), opr.name());
    /// # Ok(())
    /// # }
    /// ~~~
    pub fn try_new_with_name(id: ID, name: &'a str) -> std::result::Result<Self, String> {
        Ok(Self {
            operator_name: Some(name.try_into().map_err(|e| format!("{} for operator name", e))?),
            ..Self::new(id)
        })
    }
}