Skip to main content

coven_database/
row_key.rs

1//! Primary-key values reported by database validation.
2
3/// The primary-key values of a row, in the table's declared key order (api.md).
4#[derive(Clone, Debug, PartialEq)]
5pub struct RowKey(pub(crate) Vec<rusqlite::types::Value>);
6
7impl RowKey {
8    /// A merge row's encoded key as SQL values.
9    #[expect(
10        clippy::map_err_ignore,
11        reason = "a stored value that won't convert or decode is DamagedDatabase"
12    )]
13    pub(crate) fn decode(key: &[u8]) -> Result<Self, crate::DbError> {
14        Ok(Self(
15            coven_format::key::decode_key(key)
16                .map_err(|_| crate::DbError::DamagedDatabase)?
17                .iter()
18                .map(crate::write_encoding::sql_value)
19                .collect(),
20        ))
21    }
22
23    /// The SQL values identifying the row.
24    pub fn values(&self) -> &[rusqlite::types::Value] {
25        &self.0
26    }
27}
28
29/// Reads a key as `coven_key` gives it (api.md E4): coven's encoding of a
30/// row's key (format.md D3). A value that isn't one is
31/// `DamagedDatabase`.
32impl rusqlite::types::FromSql for RowKey {
33    fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
34        Self::decode(value.as_blob()?)
35            .map_err(|error| rusqlite::types::FromSqlError::Other(Box::new(error)))
36    }
37}
38
39impl From<&str> for RowKey {
40    fn from(value: &str) -> Self {
41        Self(vec![rusqlite::types::Value::Text(value.into())])
42    }
43}
44
45impl From<coven_foundation::uuid_text::UuidText> for RowKey {
46    fn from(value: coven_foundation::uuid_text::UuidText) -> Self {
47        Self(vec![value.into()])
48    }
49}
50
51impl<A: Into<rusqlite::types::Value>, B: Into<rusqlite::types::Value>> From<(A, B)> for RowKey {
52    fn from((first, second): (A, B)) -> Self {
53        Self(vec![first.into(), second.into()])
54    }
55}
56
57impl From<Vec<rusqlite::types::Value>> for RowKey {
58    fn from(values: Vec<rusqlite::types::Value>) -> Self {
59        Self(values)
60    }
61}