diff --git a/src/graph/dynamic.rs b/src/graph/dynamic.rs deleted file mode 100644 index 335a179..0000000 --- a/src/graph/dynamic.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::graph::node::RunnableNode; -use async_trait::async_trait; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use wasmtime::component::{bindgen, Component}; -use wasmtime::{Config, Engine, Linker, Store}; - -bindgen!(); - -#[derive(Serialize, Deserialize, Clone, JsonSchema)] -pub struct DynamicNode { - pub wasm_file: String, - pub file_paths: Vec, - pub output_file: String, -} - -pub struct DynamicNodeRunner { - pub dynamic_node: DynamicNode, -} - -#[async_trait] -impl RunnableNode for DynamicNodeRunner { - async fn run(&self) -> anyhow::Result<()> { - let mut config = Config::new(); - config.wasm_component_model(true); - let engine = Engine::new(&config)?; - // let component = Component::from_file(&engine, self.dynamic_node.wasm_file.to_owned())?; - // let mut linker = Linker::new(&engine); - // ::add_to_linker(&mut linker, |state: &mut TestState| state)?; - let mut store = Store::new( - &engine, - &self.dynamic_node, - ); - // let (bindings, _) = Dynamic::instantiate(&mut store, &component, &linker)?; - // bindings.call_greet(&mut store)?; - Ok(()) - } -} \ No newline at end of file diff --git a/src/graph/dynamic/csv_reader.rs b/src/graph/dynamic/csv_reader.rs new file mode 100644 index 0000000..2a1d44a --- /dev/null +++ b/src/graph/dynamic/csv_reader.rs @@ -0,0 +1,36 @@ +use super::{csv_row::CsvRow, dynamic_state::{vato007::ingey::types::HostCsvReader, DynamicState, ReadMapData}}; + +pub struct CsvReader { + path: String, +} + +impl HostCsvReader for DynamicState { + fn columns(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::__internal::Vec { + todo!() + } + + fn next(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::Resource { + todo!() + } + + fn has_next(&mut self,self_:wasmtime::component::Resource,) -> bool { + todo!() + } + + #[doc = " Get a row by values in one or more columns"] +fn query(&mut self,self_:wasmtime::component::Resource,values:wasmtime::component::__internal::Vec<(wasmtime::component::__internal::String,wasmtime::component::__internal::String,)>,) -> wasmtime::component::Resource { + todo!() + } + + fn read_into_string(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::__internal::String { + todo!() + } + + fn read_into_map(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::Resource { + todo!() + } + + fn drop(&mut self,rep:wasmtime::component::Resource) -> wasmtime::Result<()> { + todo!() + } +} \ No newline at end of file diff --git a/src/graph/dynamic/csv_readers.rs b/src/graph/dynamic/csv_readers.rs new file mode 100644 index 0000000..ac9aecb --- /dev/null +++ b/src/graph/dynamic/csv_readers.rs @@ -0,0 +1,15 @@ +use super::{csv_reader::CsvReader, dynamic_state::{vato007::ingey::types::HostCsvReaders, DynamicState}}; + +pub struct CsvReadersData { + +} + +impl HostCsvReaders for DynamicState { + fn get_reader(&mut self,self_:wasmtime::component::Resource,name:wasmtime::component::__internal::String,) -> Option> { + todo!() + } + + fn drop(&mut self,rep:wasmtime::component::Resource) -> wasmtime::Result<()> { + todo!() + } +} \ No newline at end of file diff --git a/src/graph/dynamic/csv_row.rs b/src/graph/dynamic/csv_row.rs new file mode 100644 index 0000000..0a3b04d --- /dev/null +++ b/src/graph/dynamic/csv_row.rs @@ -0,0 +1,34 @@ +use std::collections::BTreeMap; + +use super::dynamic_state::{vato007::ingey::types::HostCsvRow, DynamicState}; + +pub struct CsvRow { + values: BTreeMap, +} + +impl HostCsvRow for DynamicState { + fn columns(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::__internal::Vec { + let resource = self.resources.get(&self_).expect("Failed to find the required resource"); + resource.values.keys().cloned().collect() + } + + fn values(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::__internal::Vec { + let resource = self.resources.get(&self_).expect("Failed to find the required resource"); + resource.values.values().cloned().collect() + } + + fn entries(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::__internal::Vec<(wasmtime::component::__internal::String,wasmtime::component::__internal::String,)> { + let resource = self.resources.get(&self_).expect("Failed to find the required resource"); + resource.values.keys().map(|key| (key.clone(), resource.values.get(key).unwrap().clone())).collect() + } + + fn value(&mut self,self_:wasmtime::component::Resource,name:wasmtime::component::__internal::String,) -> Option { + let resource = self.resources.get(&self_).expect("Failed to find the required resource"); + resource.values.get(&name).cloned() + } + + fn drop(&mut self,rep:wasmtime::component::Resource) -> wasmtime::Result<()> { + self.resources.delete(rep)?; + Ok(()) + } +} \ No newline at end of file diff --git a/src/graph/dynamic/csv_writer.rs b/src/graph/dynamic/csv_writer.rs new file mode 100644 index 0000000..37b023f --- /dev/null +++ b/src/graph/dynamic/csv_writer.rs @@ -0,0 +1,20 @@ +use super::{dynamic_state::{vato007::ingey::types::HostCsvWriter, DynamicState}, write_map::WriteMap}; + +pub struct CsvWriterData { + +} + + +impl HostCsvWriter for DynamicState { + fn write_map(&mut self,self_:wasmtime::component::Resource,row:wasmtime::component::Resource,) -> () { + todo!() + } + + fn write_row(&mut self,self_:wasmtime::component::Resource,row:wasmtime::component::__internal::Vec<(wasmtime::component::__internal::String,wasmtime::component::__internal::String,)>,) -> () { + todo!() + } + + fn drop(&mut self,rep:wasmtime::component::Resource) -> wasmtime::Result<()> { + todo!() + } +} \ No newline at end of file diff --git a/src/graph/dynamic/dynamic_state.rs b/src/graph/dynamic/dynamic_state.rs new file mode 100644 index 0000000..8cf965a --- /dev/null +++ b/src/graph/dynamic/dynamic_state.rs @@ -0,0 +1,33 @@ +use vato007::ingey::types::Host; +use wasmtime::component::{bindgen, ResourceTable}; +pub use super::csv_row::CsvRow; +pub use super::csv_reader::CsvReader; +pub use super::write_map::WriteMap; +pub use super::csv_readers::CsvReadersData; +pub use super::csv_writer::CsvWriterData; +pub use super::read_map::ReadMapData; + +bindgen!({ + with: { + "vato007:ingey/types/csv-row": CsvRow, + "vato007:ingey/types/csv-reader": CsvReader, + "vato007:ingey/types/write-map": WriteMap, + "vato007:ingey/types/csv-readers": CsvReadersData, + "vato007:ingey/types/csv-writer": CsvWriterData, + "vato007:ingey/types/read-map": ReadMapData, + } +}); + +pub struct DynamicState { + pub resources: ResourceTable, +} + +impl DynamicState { + pub fn new() -> DynamicState { + DynamicState {resources: ResourceTable::new()} + } +} + +impl Host for DynamicState { + +} \ No newline at end of file diff --git a/src/graph/dynamic/mod.rs b/src/graph/dynamic/mod.rs new file mode 100644 index 0000000..e3cdbe2 --- /dev/null +++ b/src/graph/dynamic/mod.rs @@ -0,0 +1,48 @@ +use crate::graph::node::RunnableNode; +use async_trait::async_trait; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use wasmtime::component::{Component, Linker}; +use wasmtime::{Config, Engine, Store}; + +mod dynamic_state; +use dynamic_state::{Dynamic, DynamicState}; + +mod csv_row; +mod csv_reader; +mod write_map; +mod csv_readers; +mod csv_writer; +mod read_map; + + +#[derive(Serialize, Deserialize, Clone, JsonSchema)] +pub struct DynamicNode { + pub wasm_file_path: String, + pub input_file_paths: Vec, + pub output_file: String, +} + +// Node to run arbitrary webassembly code to transorm one or more csv files +// TODO: Create a separate node for wit that allows arbitrary files +pub struct DynamicNodeRunner { + pub dynamic_node: DynamicNode, +} + +#[async_trait] +impl RunnableNode for DynamicNodeRunner { + async fn run(&self) -> anyhow::Result<()> { + let engine = Engine::new(Config::new().wasm_component_model(true))?; + let component = Component::from_file(&engine, &self.dynamic_node.wasm_file_path)?; + let mut linker = Linker::new(&engine); + Dynamic::add_to_linker(&mut linker, |state: &mut DynamicState| state)?; + let mut store = Store::new( + &engine, + DynamicState::new() + ); + let bindings = Dynamic::instantiate(&mut store, &component, &linker)?; + // TODO: Instantiate readers + // bindings.call_evaluate(&mut store, ReadersMap{readers: vec![]}, &ReadMap {}, &Writer {})?; + Ok(()) + } +} \ No newline at end of file diff --git a/src/graph/dynamic/read_map.rs b/src/graph/dynamic/read_map.rs new file mode 100644 index 0000000..b433dee --- /dev/null +++ b/src/graph/dynamic/read_map.rs @@ -0,0 +1,15 @@ +use super::dynamic_state::{vato007::ingey::types::HostReadMap, DynamicState}; + +pub struct ReadMapData { + +} + +impl HostReadMap for DynamicState { + fn get(&mut self,self_:wasmtime::component::Resource,key:wasmtime::component::__internal::String,) -> wasmtime::component::__internal::String { + todo!() + } + + fn drop(&mut self,rep:wasmtime::component::Resource) -> wasmtime::Result<()> { + todo!() + } +} \ No newline at end of file diff --git a/src/graph/dynamic/write_map.rs b/src/graph/dynamic/write_map.rs new file mode 100644 index 0000000..6e48214 --- /dev/null +++ b/src/graph/dynamic/write_map.rs @@ -0,0 +1,19 @@ +use super::dynamic_state::{vato007::ingey::types::HostWriteMap, DynamicState}; + +pub struct WriteMap { + +} + +impl HostWriteMap for DynamicState { + fn keys(&mut self,self_:wasmtime::component::Resource,) -> wasmtime::component::__internal::Vec { + todo!() + } + + fn put(&mut self,self_:wasmtime::component::Resource,name:wasmtime::component::__internal::String,value:wasmtime::component::__internal::String,) -> () { + todo!() + } + + fn drop(&mut self,rep:wasmtime::component::Resource) -> wasmtime::Result<()> { + todo!() + } +} \ No newline at end of file diff --git a/wit/dynamic_node.wit b/wit/dynamic_node.wit index eed84e7..58dfb6a 100644 --- a/wit/dynamic_node.wit +++ b/wit/dynamic_node.wit @@ -1,35 +1,47 @@ package vato007:ingey; -world dynamic { - resource row { - get: func(name: string) -> string; +interface types { + resource csv-row { + columns: func() -> list; + values: func() -> list; + entries: func() -> list>; + value: func(name: string) -> option; } - resource reader { + resource csv-reader { columns: func() -> list; - next: func() -> row; + next: func() -> csv-row; has-next: func() -> bool; // Get a row by values in one or more columns - query: func(values: list>) -> row; + query: func(values: list>) -> csv-row; + + read-into-string: func() -> string; + read-into-map: func() -> read-map; + } + + resource write-map { + keys: func() -> list; + put: func(name: string, value: string); + } + + resource csv-readers { + get-reader: func(name: string) -> option; + } + + resource csv-writer { + write-map: func(row: write-map); + write-row: func(row: list>); } resource read-map { get: func(key: string) -> string; } +} - resource write-map { - add: func(name: string, value: string); - } - - resource readers { - get-reader: func(name: string) -> option; - } - - resource writer { - write: func(row: write-map); - } - - export evaluate: func(readers: readers, properties: read-map, writer: writer); +// This will apply to csv files only for simplicity. A separate node should be created for arbitrary readers/writers +world dynamic { + use types.{csv-readers, read-map, csv-writer}; + export evaluate: func(properties: read-map, readers: csv-readers, writer: csv-writer); } \ No newline at end of file