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