nu_protocol/engine/
env_name.rs1use std::fmt;
19use std::fmt::Debug;
20use std::hash::{Hash, Hasher};
21
22#[derive(Clone)]
24pub struct EnvName(pub(crate) String);
25
26impl Debug for EnvName {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 self.0.fmt(f)
29 }
30}
31
32impl<T: Into<String>> From<T> for EnvName {
33 fn from(name: T) -> Self {
34 EnvName(name.into())
35 }
36}
37
38impl AsRef<str> for EnvName {
39 fn as_ref(&self) -> &str {
40 &self.0
41 }
42}
43
44impl PartialEq<Self> for EnvName {
45 fn eq(&self, other: &Self) -> bool {
46 self.0.eq_ignore_ascii_case(&other.0)
48 }
49}
50
51impl Eq for EnvName {}
52
53impl Hash for EnvName {
54 fn hash<H: Hasher>(&self, state: &mut H) {
55 self.hash_case_insensitive(state);
57 }
58}
59
60impl EnvName {
61 pub fn into_string(self) -> String {
63 self.0
64 }
65
66 pub fn as_str(&self) -> &str {
68 &self.0
69 }
70
71 fn hash_case_insensitive<H: Hasher>(&self, state: &mut H) {
73 for &b in self.0.as_bytes() {
74 b.to_ascii_uppercase().hash(state);
75 }
76 }
77}
78
79#[test]
80fn test_env_name_case_insensitive() {
81 let strings1 = [
83 EnvName::from("abc"),
84 EnvName::from("Abc"),
85 EnvName::from("aBc"),
86 EnvName::from("abC"),
87 EnvName::from("ABc"),
88 EnvName::from("aBC"),
89 EnvName::from("AbC"),
90 EnvName::from("ABC"),
91 ];
92 let strings2 = [
93 EnvName::from("xyz"),
94 EnvName::from("Xyz"),
95 EnvName::from("xYz"),
96 EnvName::from("xyZ"),
97 EnvName::from("XYz"),
98 EnvName::from("xYZ"),
99 EnvName::from("XyZ"),
100 EnvName::from("XYZ"),
101 ];
102 for s1 in &strings1 {
104 for also_s1 in &strings1 {
105 assert_eq!(s1, also_s1);
106 let mut hash_set = std::collections::HashSet::new();
107 hash_set.insert(s1);
108 hash_set.insert(also_s1);
109 assert_eq!(hash_set.len(), 1);
110 }
111 }
112 for s2 in &strings2 {
114 for also_s2 in &strings2 {
115 assert_eq!(s2, also_s2);
116 let mut hash_set = std::collections::HashSet::new();
117 hash_set.insert(s2);
118 hash_set.insert(also_s2);
119 assert_eq!(hash_set.len(), 1);
120 }
121 }
122 for s1 in &strings1 {
126 for s2 in &strings2 {
127 assert_ne!(s1, s2);
128 let mut hasher1 = std::hash::DefaultHasher::new();
129 s1.hash(&mut hasher1);
130 let mut hasher2 = std::hash::DefaultHasher::new();
131 s2.hash(&mut hasher2);
132 assert_ne!(hasher1.finish(), hasher2.finish());
133 }
134 }
135}