1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::serde::{Datum, OptDatum, ReadResult, WriteLen};
use crate::types::{Deser, PKShared, PrimaryKey, SVShared, Ser, Serializable, SubValue};
use anyhow::{anyhow, Result};
use std::borrow::Borrow;
use std::cmp::{Ord, Ordering, PartialOrd};
use std::io::{Read, Seek, Write};
use std::sync::Arc;

/// A tuple containing a sub-value and a primary-key.
#[derive(PartialEq, Eq, Clone)]
pub struct SVPKShared {
    pub sv: SVShared,
    pub pk: PKShared,
}

/* SVPKShared is Serializable. */
impl Ser for SVPKShared {
    fn ser<W: Write>(&self, w: &mut W) -> Result<WriteLen> {
        let mut w_len = 0;
        w_len += *((&self.sv as &Datum).ser(w)?);
        w_len += *((&self.pk as &Datum).ser(w)?);
        Ok(WriteLen::new_manual(w_len))
    }
}
impl Deser for SVPKShared {
    fn skip<R: Read + Seek>(r: &mut R) -> Result<ReadResult<()>> {
        let sv_r_len = match OptDatum::<Datum>::skip(r)? {
            ReadResult::EOF => return Ok(ReadResult::EOF),
            ReadResult::Some(r_len, ()) => r_len,
        };
        let pk_r_len = match OptDatum::<Datum>::skip(r)? {
            ReadResult::EOF => return Err(anyhow!("SV found but PK not found.")),
            ReadResult::Some(r_len, ()) => r_len,
        };

        let r_len = sv_r_len + pk_r_len;
        return Ok(ReadResult::Some(r_len, ()));
    }
    fn deser<R: Read + Seek>(r: &mut R) -> Result<ReadResult<Self>> {
        let (sv_r_len, sv_dat) = match Datum::deser(r)? {
            ReadResult::EOF => return Ok(ReadResult::EOF),
            ReadResult::Some(r_len, dat) => (r_len, dat),
        };
        let (pk_r_len, pk_dat) = match Datum::deser(r)? {
            ReadResult::EOF => return Err(anyhow!("SV found but PK not found.")),
            ReadResult::Some(r_len, dat) => (r_len, dat),
        };

        let r_len = sv_r_len + pk_r_len;
        let svpk = SVPKShared {
            sv: SVShared::Own(Arc::new(SubValue(sv_dat))),
            pk: Arc::new(PrimaryKey(pk_dat)),
        };
        return Ok(ReadResult::Some(r_len, svpk));
    }
}
impl Serializable for SVPKShared {}

/* SVPKShared can be converted (= Borrow + Into) into PKShared. */
impl Borrow<PKShared> for SVPKShared {
    fn borrow(&self) -> &PKShared {
        &self.pk
    }
}
impl From<SVPKShared> for PKShared {
    fn from(svpk: SVPKShared) -> PKShared {
        svpk.pk
    }
}

/* SVPKShared is comparable against the same type. */
impl PartialOrd for SVPKShared {
    fn partial_cmp(&self, other: &SVPKShared) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl Ord for SVPKShared {
    fn cmp(&self, other: &SVPKShared) -> Ordering {
        self.sv.cmp(&other.sv).then_with(|| self.pk.cmp(&other.pk))
    }
}

/* SVPKShared is comparable against {SubValue, &SubValue, etc}. */
impl<O> PartialEq<O> for SVPKShared
where
    O: Borrow<SubValue>,
{
    fn eq(&self, other: &O) -> bool {
        (&self.sv as &SubValue).eq(other.borrow())
    }
}
impl<O> PartialOrd<O> for SVPKShared
where
    O: Borrow<SubValue>,
{
    /// Orders by sub-value, and *not* by primary-key.
    /// In case `self's sub-value == other's sub-value`, the absolute ordering is undefined and depends on the context. Eg:
    /// - "x vs lower bound y" := `x.partial_cmp(y).unwrap_or(Ordering::Greater)`
    /// - "x vs upper bound y" := `x.partial_cmp(y).unwrap_or(Ordering::Less)`
    fn partial_cmp(&self, other: &O) -> Option<Ordering> {
        match (&self.sv as &SubValue).cmp(other.borrow()) {
            Ordering::Equal => None,
            ord => Some(ord),
        }
    }
}