dsntk_feel/
names.rs

1//! `FEEL` name implementation.
2
3use dsntk_common::Jsonify;
4use std::fmt;
5
6/// `FEEL` name.
7#[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Clone)]
8pub struct Name(String);
9
10impl From<Vec<String>> for Name {
11  /// Converts a vector of strings into [Name].
12  fn from(value: Vec<String>) -> Self {
13    Self::new(&value.iter().map(|string| string.as_str()).collect::<Vec<&str>>())
14  }
15}
16
17impl From<Vec<&str>> for Name {
18  /// Converts a vector of string references into [Name].
19  fn from(value: Vec<&str>) -> Self {
20    Self::new(&value)
21  }
22}
23
24impl From<String> for Name {
25  /// Converts a [String] into [Name].
26  fn from(value: String) -> Self {
27    Self(value.trim().to_string())
28  }
29}
30
31impl From<&String> for Name {
32  /// Converts a reference to [String] into [Name].
33  fn from(value: &String) -> Self {
34    Self(value.trim().to_string())
35  }
36}
37
38impl From<&str> for Name {
39  /// Converts a reference to [str] into [Name].
40  fn from(value: &str) -> Self {
41    Self(value.trim().to_string())
42  }
43}
44
45impl From<Name> for String {
46  /// Converts [Name] to its [String] representation.
47  fn from(value: Name) -> Self {
48    value.0
49  }
50}
51
52impl From<&Name> for String {
53  /// Converts a reference to [Name] to its [String] representation.
54  fn from(value: &Name) -> Self {
55    value.0.clone()
56  }
57}
58
59impl fmt::Display for Name {
60  /// Implements [Display](fmt::Display) trait for [Name].
61  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62    write!(f, "{}", self.0)
63  }
64}
65
66impl Jsonify for Name {
67  /// Converts [Name] to its `JSON` representation.
68  fn jsonify(&self) -> String {
69    self.0.clone()
70  }
71}
72
73impl Name {
74  /// Creates a [Name] from string parts.
75  pub fn new(parts: &[&str]) -> Self {
76    let mut result = String::with_capacity(80);
77    let mut current;
78    let mut prev = false;
79    for (index, part) in parts.iter().map(|s| s.trim()).enumerate() {
80      current = matches!(part, "." | "/" | "-" | "'" | "+" | "*");
81      if index > 0 && !prev && !current && !part.is_empty() {
82        result.push(' ');
83      }
84      result.push_str(part);
85      prev = current;
86    }
87    Self(result)
88  }
89
90  /// Returns `true` when this name is empty.
91  pub fn is_empty(&self) -> bool {
92    self.0.is_empty()
93  }
94}