Created
June 24, 2023 10:30
-
-
Save JamesWP/4c8f3432a02f10941d118cbb4dc80c9d to your computer and use it in GitHub Desktop.
Rust structs to support sqlite like vm operations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::cell::RefCell; | |
use std::fmt::Debug; | |
use std::rc::Rc; | |
use std::rc::Weak; | |
#[derive(Debug)] | |
struct DataSource {} | |
#[derive(Debug)] | |
struct Database { | |
data_source: DataSource, | |
} | |
#[derive(Debug)] | |
struct Cursor { | |
db: Weak<RefCell<Database>>, | |
table: String, | |
} | |
struct RowValueRef { | |
cursor: Weak<RefCell<Cursor>>, | |
} | |
#[derive(Debug)] | |
enum Value { | |
Cursor(Rc<RefCell<Cursor>>), | |
Row(RowValueRef), | |
None, | |
} | |
fn open(db: &Rc<RefCell<Database>>, table_name: &str) -> Rc<RefCell<Cursor>> { | |
let weak = Rc::<RefCell<Database>>::downgrade(&db); | |
Rc::new(RefCell::new(Cursor { db: weak, table: table_name.to_owned() })) | |
} | |
fn read_value(cursor: &Rc<RefCell<Cursor>>) -> RowValueRef{ | |
let weak = Rc::<RefCell<Cursor>>::downgrade(cursor); | |
RowValueRef { cursor: weak } | |
} | |
struct VirtualMachine { | |
registers: [Value; 3], | |
database: Rc<RefCell<Database>>, | |
} | |
impl Default for DataSource { | |
fn default() -> Self { | |
Self {} | |
} | |
} | |
impl Default for Value { | |
fn default() -> Self { | |
Self::None | |
} | |
} | |
impl Default for Database { | |
fn default() -> Self { | |
Self { | |
data_source: Default::default(), | |
} | |
} | |
} | |
impl Default for VirtualMachine { | |
fn default() -> Self { | |
Self { | |
registers: Default::default(), | |
database: Default::default(), | |
} | |
} | |
} | |
impl Debug for RowValueRef { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
let mut a = f.debug_struct("RowValueRef"); | |
let a = match self.cursor.upgrade(){ | |
Some(c) => { | |
a.field("cursor", &c) | |
} | |
None => { | |
a.field("cursor", &"Dangle") | |
} | |
}; | |
a.finish() | |
} | |
} | |
impl VirtualMachine { | |
pub fn op_open_cursor(&mut self, table: &str, reg: usize) { | |
self.registers[reg] = Value::Cursor(open(&self.database, table)); | |
} | |
pub fn op_read(&mut self, cursor_reg: usize, reg: usize) { | |
match &self.registers[cursor_reg] { | |
Value::Cursor(c) => { | |
let v = read_value(c); | |
self.registers[reg] = Value::Row(v); | |
} | |
_ => panic!(), | |
} | |
} | |
pub fn op_print(&mut self, reg: usize) { | |
match &self.registers[reg] { | |
Value::Cursor(c) => { | |
println!("R{reg}: {:?}", c.borrow()); | |
} | |
Value::Row(r) => { | |
println!("R{reg}: {:?}", r); | |
} | |
Value::None => { | |
println!("R{reg}: None"); | |
} | |
} | |
} | |
} | |
fn main() { | |
println!("Hello, world!"); | |
let mut vm = VirtualMachine::default(); | |
vm.op_open_cursor("A", 0); | |
vm.op_read(0, 1); | |
vm.op_print(1); | |
vm.op_open_cursor("B", 0); | |
vm.op_print(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment