// 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 . 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, } impl ObjectId { pub fn new(id: Vec) -> ObjectId { ObjectId { id } } pub fn from_str(id_str: &str) -> Result { 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(vec![ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ]); assert_eq!(format!("{}", obj), "0001020304050607"); } #[test] fn object_id_debug() { let obj = ObjectId::new(vec![ 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(vec![ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ]); assert_eq!(obj, obj_ref); } }