Skip to content

Commit

Permalink
fix Hash impl for Chars
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Klein <mklein@bitdrift.io>
  • Loading branch information
mattklein123 committed Nov 21, 2023
1 parent 96b5395 commit a7eccd3
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion protobuf/src/chars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

use std::borrow::Borrow;
use std::fmt;
use std::hash::Hash;
use std::ops::Deref;
use std::str;

use bytes::Bytes;

/// Thin wrapper around `Bytes` which guarantees that bytes are valid UTF-8 string.
/// Should be API-compatible to `String`.
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Chars(Bytes);

impl Chars {
Expand Down Expand Up @@ -46,6 +47,17 @@ impl Chars {
}
}

// Chars can be used as the key in a HashMap in a proto map. Because Chars is a wrapper around
// Bytes, we cannot derive Hash on bytes, because hashing Bytes/u8 is not the same as hashing str.
// So here we make sure when we hash we are hashing the str otherwise we get very confusing
// results.
impl Hash for Chars {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let str_self: &str = self;
str_self.hash(state);
}
}

impl From<&'static str> for Chars {
fn from(value: &'static str) -> Self {
Chars(Bytes::from_static(value.as_bytes()))
Expand Down Expand Up @@ -102,8 +114,17 @@ impl fmt::Debug for Chars {

#[cfg(test)]
mod test {
use std::collections::HashMap;

use super::Chars;

#[test]
fn test_chars_hashmap() {
let mut table: HashMap<Chars, u64> = HashMap::new();
table.insert("foo".into(), 5);
assert_eq!(5, *table.get("foo").unwrap());
}

#[test]
#[cfg_attr(miri, ignore)] // bytes violates SB, see https://github.com/tokio-rs/bytes/issues/522
fn test_display_and_debug() {
Expand Down

0 comments on commit a7eccd3

Please sign in to comment.