about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2024-08-16T13·09+0300
committerclbot <clbot@tvl.fyi>2024-08-19T11·50+0000
commitd8640b6e67eba2e219b34da86df6842928ac87ee (patch)
tree822f3f1438309bfa13548e13daca80d6c9f9906d
parent4d5abbe232b786359659dc1c3a717e1557fa4751 (diff)
feat(tazjin/german-string): add data accessors for &str and &[u8] r/8524
Change-Id: I992e625861f79ef6d9993e8caee4e02d3fc5557e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12236
Tested-by: BuildkiteCI
Autosubmit: tazjin <tazjin@tvl.su>
Reviewed-by: tazjin <tazjin@tvl.su>
-rw-r--r--users/tazjin/german-string/src/lib.rs68
1 files changed, 67 insertions, 1 deletions
diff --git a/users/tazjin/german-string/src/lib.rs b/users/tazjin/german-string/src/lib.rs
index 813cd5b1e515..9aca9c72b8e9 100644
--- a/users/tazjin/german-string/src/lib.rs
+++ b/users/tazjin/german-string/src/lib.rs
@@ -66,11 +66,23 @@ impl GermanString {
         }
     }
 
-    fn len(&self) -> usize {
+    pub fn len(&self) -> usize {
         // SAFETY: The length field is located in the same location for both
         // variants, reading it from either is safe.
         unsafe { self.0.small.len as usize }
     }
+
+    pub fn as_bytes(&self) -> &[u8] {
+        if self.len() > 12 {
+            unsafe { std::slice::from_raw_parts(self.0.large.data, self.len()) }
+        } else {
+            unsafe { &self.0.small.data.as_ref()[..self.len()] }
+        }
+    }
+
+    pub fn as_str(&self) -> Result<&str, std::str::Utf8Error> {
+        std::str::from_utf8(self.as_bytes())
+    }
 }
 
 impl Drop for GermanString {
@@ -83,3 +95,57 @@ impl Drop for GermanString {
         }
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_empty_string() {
+        let empty = GermanString::new_transient(b"");
+
+        assert_eq!(empty.len(), 0, "empty string should be empty");
+        assert_eq!(empty.as_bytes(), b"", "empty string should contain nothing");
+        assert_eq!(
+            empty.as_str().expect("empty string is valid UTF-8"),
+            "",
+            "empty string should contain empty string"
+        );
+    }
+
+    #[test]
+    fn test_short_string() {
+        let short = GermanString::new_transient(b"meow");
+
+        assert_eq!(short.len(), 4, "'meow' is four characters");
+        assert_eq!(
+            short.as_bytes(),
+            b"meow",
+            "short string returns correct bytes"
+        );
+        assert_eq!(
+            short.as_str().expect("'meow' is valid UTF-8"),
+            "meow",
+            "short string returns correct string"
+        );
+    }
+
+    #[test]
+    fn test_long_string() {
+        let input: &str = "This code was written at https://signal.live";
+        let long = GermanString::new_transient(input.as_bytes());
+
+        assert_eq!(long.len(), 44, "long string has correct length");
+        assert_eq!(
+            long.as_bytes(),
+            input.as_bytes(),
+            "long string returns correct bytes"
+        );
+
+        assert_eq!(
+            long.as_str().expect("input is valid UTF-8"),
+            input,
+            "long string returns correct string"
+        );
+    }
+}