Add structure and interface for csv dynamic node
All checks were successful
test / test (push) Successful in 13m41s

This commit is contained in:
2025-01-18 14:25:26 +10:30
parent 65d1e9fec4
commit 9f6fa04dcf
10 changed files with 251 additions and 57 deletions

View File

@@ -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<String>,
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(())
}
}

View File

@@ -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<CsvReader>,) -> wasmtime::component::__internal::Vec<wasmtime::component::__internal::String> {
todo!()
}
fn next(&mut self,self_:wasmtime::component::Resource<CsvReader>,) -> wasmtime::component::Resource<CsvRow> {
todo!()
}
fn has_next(&mut self,self_:wasmtime::component::Resource<CsvReader>,) -> bool {
todo!()
}
#[doc = " Get a row by values in one or more columns"]
fn query(&mut self,self_:wasmtime::component::Resource<CsvReader>,values:wasmtime::component::__internal::Vec<(wasmtime::component::__internal::String,wasmtime::component::__internal::String,)>,) -> wasmtime::component::Resource<CsvRow> {
todo!()
}
fn read_into_string(&mut self,self_:wasmtime::component::Resource<CsvReader>,) -> wasmtime::component::__internal::String {
todo!()
}
fn read_into_map(&mut self,self_:wasmtime::component::Resource<CsvReader>,) -> wasmtime::component::Resource<ReadMapData> {
todo!()
}
fn drop(&mut self,rep:wasmtime::component::Resource<CsvReader>) -> wasmtime::Result<()> {
todo!()
}
}

View File

@@ -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<CsvReadersData>,name:wasmtime::component::__internal::String,) -> Option<wasmtime::component::Resource<CsvReader>> {
todo!()
}
fn drop(&mut self,rep:wasmtime::component::Resource<CsvReadersData>) -> wasmtime::Result<()> {
todo!()
}
}

View File

@@ -0,0 +1,34 @@
use std::collections::BTreeMap;
use super::dynamic_state::{vato007::ingey::types::HostCsvRow, DynamicState};
pub struct CsvRow {
values: BTreeMap<String, String>,
}
impl HostCsvRow for DynamicState {
fn columns(&mut self,self_:wasmtime::component::Resource<CsvRow>,) -> wasmtime::component::__internal::Vec<wasmtime::component::__internal::String> {
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<CsvRow>,) -> wasmtime::component::__internal::Vec<wasmtime::component::__internal::String> {
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<CsvRow>,) -> 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<CsvRow>,name:wasmtime::component::__internal::String,) -> Option<wasmtime::component::__internal::String> {
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<CsvRow>) -> wasmtime::Result<()> {
self.resources.delete(rep)?;
Ok(())
}
}

View File

@@ -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<CsvWriterData>,row:wasmtime::component::Resource<WriteMap>,) -> () {
todo!()
}
fn write_row(&mut self,self_:wasmtime::component::Resource<CsvWriterData>,row:wasmtime::component::__internal::Vec<(wasmtime::component::__internal::String,wasmtime::component::__internal::String,)>,) -> () {
todo!()
}
fn drop(&mut self,rep:wasmtime::component::Resource<CsvWriterData>) -> wasmtime::Result<()> {
todo!()
}
}

View File

@@ -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 {
}

48
src/graph/dynamic/mod.rs Normal file
View File

@@ -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<String>,
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(())
}
}

View File

@@ -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<ReadMapData>,key:wasmtime::component::__internal::String,) -> wasmtime::component::__internal::String {
todo!()
}
fn drop(&mut self,rep:wasmtime::component::Resource<ReadMapData>) -> wasmtime::Result<()> {
todo!()
}
}

View File

@@ -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<WriteMap>,) -> wasmtime::component::__internal::Vec<wasmtime::component::__internal::String> {
todo!()
}
fn put(&mut self,self_:wasmtime::component::Resource<WriteMap>,name:wasmtime::component::__internal::String,value:wasmtime::component::__internal::String,) -> () {
todo!()
}
fn drop(&mut self,rep:wasmtime::component::Resource<WriteMap>) -> wasmtime::Result<()> {
todo!()
}
}

View File

@@ -1,35 +1,47 @@
package vato007:ingey; package vato007:ingey;
world dynamic { interface types {
resource row { resource csv-row {
get: func(name: string) -> string; columns: func() -> list<string>;
values: func() -> list<string>;
entries: func() -> list<tuple<string, string>>;
value: func(name: string) -> option<string>;
} }
resource reader { resource csv-reader {
columns: func() -> list<string>; columns: func() -> list<string>;
next: func() -> row; next: func() -> csv-row;
has-next: func() -> bool; has-next: func() -> bool;
// Get a row by values in one or more columns // Get a row by values in one or more columns
query: func(values: list<tuple<string, string>>) -> row; query: func(values: list<tuple<string, string>>) -> csv-row;
read-into-string: func() -> string;
read-into-map: func() -> read-map;
}
resource write-map {
keys: func() -> list<string>;
put: func(name: string, value: string);
}
resource csv-readers {
get-reader: func(name: string) -> option<csv-reader>;
}
resource csv-writer {
write-map: func(row: write-map);
write-row: func(row: list<tuple<string, string>>);
} }
resource read-map { resource read-map {
get: func(key: string) -> string; get: func(key: string) -> string;
} }
}
resource write-map { // This will apply to csv files only for simplicity. A separate node should be created for arbitrary readers/writers
add: func(name: string, value: string); world dynamic {
} use types.{csv-readers, read-map, csv-writer};
export evaluate: func(properties: read-map, readers: csv-readers, writer: csv-writer);
resource readers {
get-reader: func(name: string) -> option<reader>;
}
resource writer {
write: func(row: write-map);
}
export evaluate: func(readers: readers, properties: read-map, writer: writer);
} }