| Crates.io | kotoba-db-core |
| lib.rs | kotoba-db-core |
| version | 0.1.16 |
| created_at | 2025-09-18 02:59:29.371743+00 |
| updated_at | 2025-09-18 02:59:29.371743+00 |
| description | Core database abstractions for Kotoba |
| homepage | https://github.com/com-junkawasaki/kotoba |
| repository | https://github.com/com-junkawasaki/kotoba |
| max_upload_size | |
| id | 1844190 |
| size | 63,833 |
Core traits, data structures, and transaction logic for KotobaDB. This crate provides the foundational types and interfaces that all KotobaDB implementations must satisfy.
kotoba-db-core defines the fundamental abstractions that make KotobaDB work:
Value, Block, NodeBlock, EdgeBlock, CidStorageEngine trait for pluggable backendsThe fundamental data type for all properties and values:
pub enum Value {
String(String),
Int(i64),
Float(f64),
Bool(bool),
Bytes(Vec<u8>),
Link(Cid), // Reference to another block
}
Content-addressed data blocks:
pub enum Block {
Node(NodeBlock),
Edge(EdgeBlock),
}
Cryptographic content identifier using BLAKE3:
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Cid([u8; 32]);
The core abstraction for pluggable storage backends:
#[async_trait]
pub trait StorageEngine: Send + Sync {
/// Store a key-value pair
async fn put(&mut self, key: &[u8], value: &[u8]) -> Result<()>;
/// Retrieve a value by key
async fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>>;
/// Delete a key-value pair
async fn delete(&mut self, key: &[u8]) -> Result<()>;
/// Scan keys with a prefix
async fn scan(&self, prefix: &[u8]) -> Result<Vec<(Vec<u8>, Vec<u8>)>>;
}
The trait provides convenient methods for working with content-addressed blocks:
impl dyn StorageEngine {
/// Store a content-addressed block
pub async fn put_block(&mut self, block: &Block) -> Result<Cid>
/// Retrieve a content-addressed block
pub async fn get_block(&self, cid: &Cid) -> Result<Option<Block>>
}
Represents a graph node with properties:
pub struct NodeBlock {
pub properties: BTreeMap<String, Value>,
}
Represents a graph edge between nodes:
pub struct EdgeBlock {
pub source: Cid,
pub target: Cid,
pub properties: BTreeMap<String, Value>,
}
All blocks are content-addressed using CID:
impl Block {
/// Compute the CID for this block
pub fn cid(&self) -> Result<Cid>
/// Serialize to CBOR bytes
pub fn to_bytes(&self) -> Result<Vec<u8>>
/// Deserialize from CBOR bytes
pub fn from_bytes(bytes: &[u8]) -> Result<Self>
}
use kotoba_db_core::{StorageEngine, Block, Cid};
pub struct MyStorageEngine {
// Your storage implementation
}
#[async_trait::async_trait]
impl StorageEngine for MyStorageEngine {
async fn put(&mut self, key: &[u8], value: &[u8]) -> Result<()> {
// Your put implementation
Ok(())
}
async fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
// Your get implementation
Ok(None)
}
async fn delete(&mut self, key: &[u8]) -> Result<()> {
// Your delete implementation
Ok(())
}
async fn scan(&self, prefix: &[u8]) -> Result<Vec<(Vec<u8>, Vec<u8>)>> {
// Your scan implementation
Ok(vec![])
}
}
use kotoba_db_core::{Block, NodeBlock, Value};
use std::collections::BTreeMap;
// Create a node
let mut properties = BTreeMap::new();
properties.insert("name".to_string(), Value::String("Alice".to_string()));
properties.insert("age".to_string(), Value::Int(30));
let node = NodeBlock { properties };
let block = Block::Node(node);
// Compute CID
let cid = block.cid()?;
// Serialize
let bytes = block.to_bytes()?;
// Deserialize
let restored_block = Block::from_bytes(&bytes)?;
This crate is designed to be:
serde: Serialization frameworkciborium: CBOR serializationblake3: Cryptographic hashingasync-trait: Async trait supportanyhow: Error handlingcargo test --package kotoba-db-core
Licensed under the MIT License.