Skip to content

Instantly share code, notes, and snippets.

@JamesWP
Created June 24, 2023 10:30
Show Gist options
  • Save JamesWP/4c8f3432a02f10941d118cbb4dc80c9d to your computer and use it in GitHub Desktop.
Save JamesWP/4c8f3432a02f10941d118cbb4dc80c9d to your computer and use it in GitHub Desktop.
Rust structs to support sqlite like vm operations
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