diff --git a/src/main.rs b/src/main.rs index 6194287..2de4642 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,5 +24,15 @@ fn main() { Ok(x) => x, }; - store.get_creds("nya".to_string(), "meow".to_string()); + let (key, specifier) = ("nya".to_string(), "meow".to_string()); + + match store.get_creds(&key, &specifier) { + Some(x) => { + println!("Credentials: {:?}", x); + } + None => println!( + "Credentials for key '{}' and specifier '{}' not found...", + key, specifier + ), + } } diff --git a/src/store/local.rs b/src/store/local.rs index e730212..89ff8b8 100644 --- a/src/store/local.rs +++ b/src/store/local.rs @@ -4,8 +4,7 @@ use std::{ fs::File, hash::{Hash, Hasher}, io::{BufReader, Read, Seek, SeekFrom, Write}, - iter::TakeWhile, - path::{Iter, Path}, + path::Path, }; use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit, Nonce}; @@ -230,7 +229,7 @@ fn try_create_store(path: &String, passphrase: &Vec) -> bool { let meta = LocalStoreMeta { record_count: 0, specifier_count: 0, - index_node_arity: 64, + index_node_arity: 16, data_block_size: 8092, data_offset: 0, }; @@ -254,6 +253,13 @@ fn try_create_store(path: &String, passphrase: &Vec) -> bool { header.chksum_crc = header.get_checksum(); let mut index_block: Vec = vec![0; meta.data_block_size as usize]; + let root_node_buf = IndexNode { + node_type: IndexNodeType::Leaf, + children: Vec::new(), + } + .serialize(&meta); + + index_block[0..root_node_buf.len()].copy_from_slice(&root_node_buf); let mut buf = serialize_header(&header); @@ -500,20 +506,25 @@ impl LocalRecord { } impl Store for LocalStore { - fn get_creds(&self, specifier: String, key: String) -> Option { - self.btree_find_key(&key); - todo!() + fn get_creds(&self, specifier: &String, key: &String) -> Option { + match self.btree_find_key(&key) { + Some(x) => { + println!("Found: {}", x); + todo!() + } + None => return None, + } } - fn get_creds_by_specifier(&self, specifier: String) -> Vec { + fn get_creds_by_specifier(&self, specifier: &String) -> Vec { todo!() } fn store_creds( &self, - specifier: String, - key: String, - value: Vec, + specifier: &String, + key: &String, + value: &Vec, r#type: RecordType, meta: Option, ) { @@ -521,11 +532,11 @@ impl Store for LocalStore { } } -#[derive(PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] enum IndexNodeType { - Internal, - Leaf, - Invalid, + Internal = 1, + Leaf = 2, + Invalid = 0, } impl From for IndexNodeType { @@ -557,6 +568,20 @@ impl IndexNode { fn len(&self) -> usize { self.children.len() } + + fn serialize(&self, meta: &LocalStoreMeta) -> Vec { + let mut buf: Vec = vec![0; 16 * meta.index_node_arity as usize + 2]; + + let mut cnt = 2; + for child in self.children() { + buf[cnt..(cnt + 8)].copy_from_slice(&child.key.to_be_bytes()); + buf[(cnt + 8)..(cnt + 16)].copy_from_slice(&child.pointer.to_be_bytes()); + cnt += 16; + } + + buf[0] = self.node_type as u8; + buf + } } impl LocalStore { @@ -740,7 +765,7 @@ mod tests { StoreRecord, }; - use super::LocalRecord; + use super::{IndexNode, IndexNodeEntry, IndexNodeType, LocalRecord}; #[test] fn header_size_const_greater_than_realsize() { @@ -816,4 +841,62 @@ mod tests { assert_eq!(serialized, reserialized); } + + #[test] + fn index_node_serialize() { + let root = IndexNode { + node_type: IndexNodeType::Internal, + children: vec![IndexNodeEntry { + key: 1, + pointer: 258, + }], + }; + + let leaf = IndexNode { + node_type: IndexNodeType::Leaf, + children: vec![ + IndexNodeEntry { + key: 1, + pointer: 516, + }, + IndexNodeEntry { + key: 4, + pointer: 520, + }, + IndexNodeEntry { + key: 16, + pointer: 524, + }, + ], + }; + + let meta = super::LocalStoreMeta { + record_count: 3, + specifier_count: 0, + index_node_arity: 16, + data_block_size: 8192, + data_offset: 0, + }; + + let root_bytes = root.serialize(&meta); + let leaf_bytes = leaf.serialize(&meta); + + assert_eq!(IndexNodeType::from(root_bytes[0]), root.node_type); + assert_eq!(IndexNodeType::from(leaf_bytes[0]), leaf.node_type); + + assert_eq!(root_bytes[2..10], root.children[0].key.to_be_bytes()); + assert_eq!(root_bytes[10..18], root.children[0].pointer.to_be_bytes()); + assert!(root_bytes.iter().skip(18).all(|x| *x == 0u8)); + + let mut cnt = 2; + for child in leaf.children { + assert_eq!(leaf_bytes[cnt..(cnt + 8)], child.key.to_be_bytes()); + assert_eq!( + leaf_bytes[(cnt + 8)..(cnt + 16)], + child.pointer.to_be_bytes() + ); + cnt += 16; + } + assert!(root_bytes.iter().skip(cnt).all(|x| *x == 0u8)); + } } diff --git a/src/store/mod.rs b/src/store/mod.rs index 06e8464..110a838 100644 --- a/src/store/mod.rs +++ b/src/store/mod.rs @@ -39,13 +39,13 @@ impl From for RecordType { } pub trait Store { - fn get_creds(&self, specifier: String, key: String) -> Option; - fn get_creds_by_specifier(&self, specifier: String) -> Vec; + fn get_creds(&self, specifier: &String, key: &String) -> Option; + fn get_creds_by_specifier(&self, specifier: &String) -> Vec; fn store_creds( &self, - specifier: String, - key: String, - value: Vec, + specifier: &String, + key: &String, + value: &Vec, r#type: RecordType, meta: Option, ); diff --git a/src/store/server.rs b/src/store/server.rs index be0f756..228f446 100644 --- a/src/store/server.rs +++ b/src/store/server.rs @@ -1,6 +1,6 @@ use reqwest::header::HeaderValue; -use super::{Store, StoreRecord, RecordType}; +use super::{RecordType, Store, StoreRecord}; pub struct ServerStore { address: String, @@ -41,19 +41,19 @@ impl ServerStore { } impl Store for ServerStore { - fn get_creds(&self, specifier: String, key: String) -> Option { + fn get_creds(&self, specifier: &String, key: &String) -> Option { todo!() } - fn get_creds_by_specifier(&self, specifier: String) -> Vec { + fn get_creds_by_specifier(&self, specifier: &String) -> Vec { todo!() } fn store_creds( &self, - specifier: String, - key: String, - value: Vec, + specifier: &String, + key: &String, + value: &Vec, r#type: RecordType, meta: Option, ) {