You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.9 KiB
110 lines
2.9 KiB
// This file is part of bsv.
|
|
//
|
|
// bsv is free software: you can redistribute it and/or modify it under the
|
|
// terms of the GNU Affero General Public License as published by the Free
|
|
// Software Foundation, either version 3 of the License, or (at your option)
|
|
// any later version.
|
|
//
|
|
// cdb is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
|
// more details.
|
|
//
|
|
// You should have received a copy of the Affero GNU General Public License
|
|
// along with cdb. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
use std::fmt;
|
|
|
|
use super::error::*;
|
|
|
|
|
|
/// A unique identifier for an object.
|
|
///
|
|
/// This is the handle used to referenc an Object. This is an opaque type that uniquely identify an
|
|
/// object. It can be compared to another ObjectId, be hashed and that's about it.
|
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub struct ObjectId {
|
|
id: Vec<u8>,
|
|
}
|
|
|
|
|
|
impl ObjectId {
|
|
pub fn new(id: &[u8]) -> ObjectId {
|
|
ObjectId {
|
|
id: id.into(),
|
|
}
|
|
}
|
|
|
|
pub fn from_str(id_str: &str) -> Result<ObjectId> {
|
|
if id_str.len() % 2 != 0 {
|
|
return Err(ErrorKind::InvalidObjectIdSize.into());
|
|
}
|
|
|
|
let byte_count = id_str.len() / 2;
|
|
let mut id = Vec::with_capacity(byte_count);
|
|
|
|
for byte_index in 0..byte_count {
|
|
let str_index = byte_index * 2;
|
|
let byte_str = id_str.get(str_index..(str_index + 2))
|
|
.ok_or(ErrorKind::InvalidObjectIdCharacter)?;
|
|
id.push(u8::from_str_radix(byte_str, 16)
|
|
.or(Err(ErrorKind::InvalidObjectIdCharacter))?);
|
|
}
|
|
|
|
Ok(ObjectId {
|
|
id
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
impl fmt::Display for ObjectId {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
|
|
for byte in self.id.iter() {
|
|
write!(f, "{:02x}", byte)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
|
|
impl fmt::Debug for ObjectId {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
|
|
write!(f, "ObjectId::new(\"{}\")", self)
|
|
}
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::ObjectId;
|
|
|
|
#[test]
|
|
fn object_id_display() {
|
|
let obj = ObjectId::new(&[
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
]);
|
|
|
|
assert_eq!(format!("{}", obj), "0001020304050607");
|
|
}
|
|
|
|
#[test]
|
|
fn object_id_debug() {
|
|
let obj = ObjectId::new(&[
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
]);
|
|
|
|
assert_eq!(format!("{:?}", obj), "ObjectId::new(\"0001020304050607\")");
|
|
}
|
|
|
|
#[test]
|
|
fn str_to_object_id() {
|
|
let obj = ObjectId::from_str("0001020304050607").unwrap();
|
|
let obj_ref = ObjectId::new(&[
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
]);
|
|
|
|
assert_eq!(obj, obj_ref);
|
|
}
|
|
}
|
|
|