pgvector/
bit.rs

1#[cfg(feature = "diesel")]
2use crate::diesel_ext::bit::BitType;
3
4#[cfg(feature = "diesel")]
5use diesel::{deserialize::FromSqlRow, expression::AsExpression};
6
7/// A bit string.
8#[derive(Clone, Debug, PartialEq, Eq)]
9#[cfg_attr(feature = "diesel", derive(FromSqlRow, AsExpression))]
10#[cfg_attr(feature = "diesel", diesel(sql_type = BitType))]
11pub struct Bit {
12    pub(crate) len: usize,
13    pub(crate) data: Vec<u8>,
14}
15
16impl Bit {
17    /// Creates a bit string from a slice of bits.
18    pub fn new(data: &[bool]) -> Bit {
19        let len = data.len();
20        let mut bytes = vec![0; (len + 7) / 8];
21        for (i, v) in data.iter().enumerate() {
22            bytes[i / 8] |= u8::from(*v) << (7 - (i % 8));
23        }
24        Bit { len, data: bytes }
25    }
26
27    /// Creates a bit string from a slice of bytes.
28    pub fn from_bytes(data: &[u8]) -> Bit {
29        Bit {
30            len: data.len().checked_mul(8).unwrap(),
31            data: data.to_vec(),
32        }
33    }
34
35    /// Returns the number of bits in the bit string.
36    pub fn len(&self) -> usize {
37        self.len
38    }
39
40    /// Returns whether the bit string is empty.
41    pub fn is_empty(&self) -> bool {
42        self.len == 0
43    }
44
45    /// Returns the bit string as a slice of bytes.
46    pub fn as_bytes(&self) -> &[u8] {
47        self.data.as_slice()
48    }
49
50    #[cfg(any(feature = "postgres", feature = "sqlx", feature = "diesel"))]
51    pub(crate) fn from_sql(buf: &[u8]) -> Result<Bit, Box<dyn std::error::Error + Sync + Send>> {
52        let len = i32::from_be_bytes(buf[0..4].try_into()?).try_into()?;
53        let data = buf[4..4 + (len + 7) / 8].to_vec();
54
55        Ok(Bit { len, data })
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use crate::Bit;
62
63    #[test]
64    fn test_from_bytes() {
65        let vec = Bit::from_bytes(&[0b00000000, 0b11111111]);
66        assert_eq!(16, vec.len());
67        assert_eq!(&[0b00000000, 0b11111111], vec.as_bytes());
68    }
69
70    #[test]
71    fn test_as_bytes() {
72        let vec = Bit::new(&[true, false, true]);
73        assert_eq!(3, vec.len());
74        assert_eq!(&[0b10100000], vec.as_bytes());
75    }
76
77    #[test]
78    fn test_is_empty() {
79        let vec = Bit::new(&[]);
80        assert_eq!(0, vec.len());
81        assert!(vec.is_empty());
82    }
83}