1use crate::{Literal, Namespace};
2
3#[derive(Debug, PartialEq, Eq, Hash, Clone)]
6pub struct Class {
7 pub namespace: Namespace,
8 pub local_name: String,
9}
10
11impl std::fmt::Display for Class {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 write!(
15 f,
16 "{}{}",
17 self.namespace.name.as_str(),
18 self.local_name.as_str()
19 )
20 }
21}
22
23impl Class {
24 pub fn declare(namespace: Namespace, local_name: &str) -> Self {
25 Self { namespace, local_name: local_name.to_string() }
26 }
27
28 pub fn as_iri(&self) -> Result<iri_string::types::IriReferenceString, ekg_error::Error> {
30 Ok(iri_string::types::IriReferenceString::try_from(
31 format!("{}{}", self.namespace.iri, self.local_name),
32 )?)
33 }
34
35 #[allow(clippy::needless_lifetimes)]
36 pub fn display_turtle<'a>(&'a self) -> impl std::fmt::Display + 'a {
37 struct TurtleClass<'a>(&'a Class);
38 impl<'a> std::fmt::Display for TurtleClass<'a> {
39 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40 write!(
41 f,
42 "{}{}",
43 self.0.namespace.name, self.0.local_name
44 )
45 }
46 }
47 TurtleClass(self)
48 }
49
50 pub fn plural_label(&self) -> String {
51 if self.local_name.ends_with('y') {
52 let regex = fancy_regex::Regex::new(r"y$").expect("Failed to create regex");
53 regex.replace(self.local_name.as_str(), "ies").to_string()
54 } else {
55 format!("{}s", self.local_name)
56 }
57 }
58
59 pub fn is_literal(&self, literal: &Literal) -> bool {
62 if let Some(that_iri) = literal.as_iri_ref() {
63 if let Ok(this_iri) = self.as_iri() {
64 that_iri == this_iri
65 } else {
66 let iri = self.to_string();
67 literal.to_string() == iri
68 }
69 } else {
70 false
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use {
78 crate::{class::Class, DataType, Literal},
79 super::Namespace,
80 };
81
82 #[test]
83 fn test_a_class_01() {
84 let namespace = Namespace::declare(
85 "test:",
86 "https://whatever.com/test#".to_string().try_into().unwrap(),
87 )
89 .unwrap();
90 let class = Class::declare(namespace, "SomeClass");
91 let s = format!("{:}", class);
92 assert_eq!(s, "test:SomeClass")
93 }
94
95 #[test]
96 fn test_a_class_02() {
97 let namespace = Namespace::declare(
98 "test:",
99 iri_string::types::IriReferenceString::try_from("https://whatever.com/test#")
100 .unwrap()
101 .try_into()
102 .unwrap(),
103 )
104 .unwrap();
105 let class = Class::declare(namespace, "SomeClass");
106 let s = format!("{}", class.as_iri().unwrap());
107 assert_eq!(s, "https://whatever.com/test#SomeClass");
108 }
109
110 #[test]
111 fn test_is_literal() {
112 let namespace = Namespace::declare(
113 "test:",
114 iri_string::types::IriReferenceString::try_from("https://whatever.com/test#")
115 .unwrap()
116 .try_into()
117 .unwrap(),
118 )
119 .unwrap();
120 let class = Class::declare(namespace, "SomeClass");
121 let literal = Literal::from_type_and_buffer(
122 DataType::AnyUri,
123 "https://whatever.com/test#SomeClass",
124 None,
125 )
126 .unwrap();
127 assert!(literal.is_some());
128 assert_eq!(
129 class.as_iri().unwrap().to_string().as_str(),
130 "https://whatever.com/test#SomeClass"
131 );
132 assert!(class.is_literal(&literal.unwrap()))
133 }
134}