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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
use crate::*;

use std::any::Any;

//能静态确定编码后大小
pub trait RawFixedBytes {
    fn raw_bytes() -> Option<usize> {
        None
    }
    fn raw_max_bytes() -> Option<usize> {
        Self::raw_bytes()
    }
    fn raw_min_bytes() -> Option<usize> {
        Self::raw_bytes()
    }
}

/*
// TODO rust stable稳定版本支持模板偏特化后,再把raw_hash_code从RawEncode里面提取出来单独的trait
pub trait RawHashCode {
    fn raw_hash_encode(&self) -> BuckyResult<HashValue>;
}


impl<T: RawEncode> RawHashCode for T {
    fn raw_hash_encode(&self) -> BuckyResult<HashValue> {
        let size = self.raw_measure(&None)?;
        let mut buf = vec![0u8;size];

        let remain_buf = self.raw_encode(&mut buf, &None)?;
        let remain_len = remain_buf.len();
        let encoded_buf = &buf[..(buf.len() - remain_len)];

        let hash = hash_data(encoded_buf);

        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
        Ok(HashValue::from(hash_slice))
    }
}
*/

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum RawEncodePurpose {
    // 默认值,为序列化而编码,需要是完整编码
    Serialize,

    // 为计算hash而编码
    Hash,
}

#[derive(Debug, Clone)]
pub struct RawDecodeOption {
    pub version: u8,
    pub format: u8,
}

impl Default for RawDecodeOption {
    fn default() -> Self {
        Self {
            version: 0,
            format: OBJECT_CONTENT_CODEC_FORMAT_RAW,
        }
    }
}

//编码
pub trait RawEncode {
    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize>;
    fn raw_encode<'a>(
        &self,
        buf: &'a mut [u8],
        purpose: &Option<RawEncodePurpose>,
    ) -> BuckyResult<&'a mut [u8]>;
    fn raw_tail_encode<'a>(
        &self,
        buf: &'a mut [u8],
        purpose: &Option<RawEncodePurpose>,
    ) -> BuckyResult<&'a [u8]> {
        let remain_buf = self.raw_encode(buf, purpose)?;
        let remain_len = remain_buf.len();
        Ok(&buf[..(buf.len() - remain_len)])
    }

    // 直接编码到buffer
    fn raw_encode_to_buffer(&self) -> BuckyResult<Vec<u8>> {
        let size = self.raw_measure(&None)?;
        let mut encode_buf = vec![0u8; size];

        let buf = self.raw_encode(&mut encode_buf, &None)?;
        assert_eq!(buf.len(), 0);

        Ok(encode_buf)
    }

    // 计算对象的hash
    fn raw_hash_value(&self) -> BuckyResult<HashValue> {
        let encoded_buf = self.raw_hash_encode()?;
        Ok(self.hash_buf(&encoded_buf))
    }

    fn hash_buf(&self, encoded_buf: &[u8]) -> HashValue {
        hash_data(encoded_buf)
    }

    // 默认hash编码实现,子类可以覆盖
    fn raw_hash_encode(&self) -> BuckyResult<Vec<u8>> {
        let size = self.raw_measure(&Some(RawEncodePurpose::Hash))?;
        let mut buf = vec![0u8; size];
        let remain_buf = self.raw_encode(&mut buf, &Some(RawEncodePurpose::Hash))?;
        assert!(remain_buf.len() == 0);

        Ok(buf)
    }
}

pub trait RawEncodeWithContext<Context> {
    fn raw_measure_with_context(
        &self,
        _: &mut Context,
        purpose: &Option<RawEncodePurpose>,
    ) -> BuckyResult<usize>;
    fn raw_encode_with_context<'a>(
        &self,
        buf: &'a mut [u8],
        _: &mut Context,
        purpose: &Option<RawEncodePurpose>,
    ) -> BuckyResult<&'a mut [u8]>;
    fn raw_tail_encode_with_context<'a>(
        &self,
        buf: &'a mut [u8],
        context: &mut Context,
        purpose: &Option<RawEncodePurpose>,
    ) -> BuckyResult<&'a [u8]> {
        let remain_buf = self.raw_encode_with_context(buf, context, purpose)?;
        let remain_len = remain_buf.len();
        Ok(&buf[..(buf.len() - remain_len)])
    }
}

//解码
pub trait RawDecode<'de>: Sized {
    // 不带opt的解码,默认一般实现此方法
    fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])>;

    // 带opt的解码,如果想使用版本等高级解码特性,需要实现此方法
    fn raw_decode_with_option(
        buf: &'de [u8],
        _opt: &RawDecodeOption,
    ) -> BuckyResult<(Self, &'de [u8])> {
        Self::raw_decode(buf)
    }

    /*
    fn raw_hash_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8], HashValue)> {
        let (v, next_buf) = Self::raw_decode(buf)?;
        let hash = hash_data(&buf[..(buf.len() - next_buf.len())]);
        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
        Ok((v, next_buf, HashValue::from(hash_slice)))
    }
    */
}

pub trait RawDecodeWithContext<'de, Context>: Sized {
    fn raw_decode_with_context(buf: &'de [u8], _: Context) -> BuckyResult<(Self, &'de [u8])>;

    /*
    fn raw_hash_decode_with_context(
        buf: &'de [u8],
        context: Context,
    ) -> BuckyResult<(Self, &'de [u8], HashValue)> {
        let (v, next_buf) = Self::raw_decode_with_context(buf, context)?;
        let hash = hash_data(&buf[..(buf.len() - next_buf.len())]);
        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
        Ok((v, next_buf, HashValue::from(hash_slice)))
    }
    */
}

pub trait RawMergable: Clone + Any {
    fn raw_merge_ok(&self, other: &Self) -> bool;
}

impl<T: RawEncode + Eq + Clone + Any> RawMergable for T {
    fn raw_merge_ok(&self, other: &Self) -> bool {
        self.eq(other)
    }
}

#[cfg(test)]
mod test {
    use crate::*;

    #[test]
    fn test_hash() {
        let buf = "test_hash_buf".as_bytes();
        let hash = hash_data(buf);

        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
    
        let hash2 = HashValue::from(hash_slice);
        assert_eq!(hash, hash2);
    }
}