basyx_rs/lang_string.rs
1// SPDX-FileCopyrightText: 2021 Fraunhofer Institute for Experimental Software Engineering IESE
2//
3// SPDX-License-Identifier: MIT
4
5use serde::{Deserialize, Serialize};
6use std::str::FromStr;
7
8#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
9pub struct LangString {
10    pub language: String,
11    pub text: String,
12}
13
14impl LangString {
15    pub fn new(language: String, text: String) -> Self {
16        Self { language, text }
17    }
18}
19
20impl FromStr for LangString {
21    type Err = ();
22
23    /// The specification mentions an RDF/Turtle syntax that looks like this: "Hello"@en
24    ///
25    /// This implementation of from_str takes a &str in this syntax and returns the LangString or Err.
26    ///
27    /// # Example
28    ///
29    /// ```
30    /// use std::str::FromStr;
31    /// use basyx_rs::LangString;
32    ///
33    /// let expected = LangString::new("EN".to_string(), "Current temperature".to_string());
34    /// let actual = LangString::from_str("\"Current temperature\"@EN").ok().unwrap();
35    ///
36    /// assert_eq!(actual, expected);
37    /// ```
38    fn from_str(s: &str) -> Result<Self, Self::Err> {
39        let lang_string: Vec<&str> = s.split('@').collect();
40
41        if lang_string.len() != 2 {
42            Err(())
43        } else {
44            let mut txt = String::from(lang_string[0]);
45
46            // remove first character (")
47            if !txt.is_empty() {
48                txt.remove(0);
49            }
50
51            // remove last character (")
52            if !txt.is_empty() {
53                txt.pop();
54            }
55
56            Ok(LangString {
57                language: lang_string[1].to_string(),
58                text: txt,
59            })
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_turtle_syntax() {
70        // arrange
71        let expected = LangString::new("EN".to_string(), "Current temperature".to_string());
72
73        // act
74        let actual = LangString::from_str("\"Current temperature\"@EN")
75            .ok()
76            .unwrap();
77
78        // assert
79        assert_eq!(actual, expected);
80    }
81}