Constant LIB_RS
Source pub const LIB_RS: &str = "#![cfg_attr(target_arch = \"wasm32\", no_std)]\n\n#[cfg(target_arch = \"wasm32\")]\nextern crate alloc;\n\nmod data;\n\n#[cfg(target_arch = \"wasm32\")]\nuse alloc::{format, string::String, string::ToString, vec::Vec};\n#[cfg(not(target_arch = \"wasm32\"))]\nuse greentic_interfaces_host::bindings::exports::greentic::interfaces_pack::component_api::ProviderMeta;\n#[cfg(not(target_arch = \"wasm32\"))]\nconst _: fn(ProviderMeta) = |_meta| {};\nuse serde::{Deserialize, Serialize};\nuse serde_json::Value;\n#[cfg(not(target_arch = \"wasm32\"))]\nuse std::vec::Vec;\n\n#[derive(Debug, Clone, Serialize)]\npub struct FlowInfo {\n pub id: String,\n pub human_name: Option<String>,\n pub description: Option<String>,\n}\n\n#[derive(Debug, Clone, Serialize)]\npub struct SchemaDoc {\n pub flow_id: String,\n pub schema_json: serde_json::Value,\n}\n\n#[derive(Debug, Clone, Serialize)]\npub struct PrepareResult {\n pub status: String,\n pub error: Option<String>,\n}\n\n#[derive(Debug, Clone, Serialize)]\npub struct RunResult {\n pub status: String,\n pub output: Option<serde_json::Value>,\n pub error: Option<String>,\n}\n\n#[derive(Debug, Clone, Serialize)]\npub struct A2AItem {\n pub title: String,\n pub flow_id: String,\n}\n\npub trait PackExport {\n fn list_flows(&self) -> Vec<FlowInfo>;\n fn get_flow_schema(&self, flow_id: &str) -> Option<SchemaDoc>;\n fn prepare_flow(&self, flow_id: &str) -> PrepareResult;\n fn run_flow(&self, flow_id: &str, input: serde_json::Value) -> RunResult;\n fn a2a_search(&self, query: &str) -> Vec<A2AItem>;\n}\n\npub use data::{FLOWS, MANIFEST_CBOR, TEMPLATES};\n\npub fn manifest_cbor() -> &\'static [u8] {\n data::MANIFEST_CBOR\n}\n\npub fn manifest_value() -> Value {\n serde_cbor::from_slice(data::MANIFEST_CBOR)\n .expect(\"generated manifest bytes should always be valid CBOR\")\n}\n\npub fn manifest_as<T>() -> T\nwhere\n T: for<\'de> Deserialize<\'de>,\n{\n serde_cbor::from_slice(data::MANIFEST_CBOR)\n .expect(\"generated manifest matches the requested type\")\n}\n\npub fn flows() -> &\'static [(&\'static str, &\'static str)] {\n data::FLOWS\n}\n\npub fn templates() -> &\'static [(&\'static str, &\'static [u8])] {\n data::TEMPLATES\n}\n\npub fn template_by_path(path: &str) -> Option<&\'static [u8]> {\n data::TEMPLATES\n .iter()\n .find(|(logical, _)| *logical == path)\n .map(|(_, bytes)| *bytes)\n}\n\n#[derive(Debug, Default)]\npub struct Component;\n\nimpl PackExport for Component {\n fn list_flows(&self) -> Vec<FlowInfo> {\n flows()\n .iter()\n .map(|(id, _)| FlowInfo {\n id: (*id).to_string(),\n human_name: None,\n description: None,\n })\n .collect()\n }\n\n fn get_flow_schema(&self, flow_id: &str) -> Option<SchemaDoc> {\n flows()\n .iter()\n .find(|(id, _)| *id == flow_id)\n .map(|(id, _)| SchemaDoc {\n flow_id: (*id).to_string(),\n schema_json: serde_json::json!({}),\n })\n }\n\n fn prepare_flow(&self, flow_id: &str) -> PrepareResult {\n if flows().iter().any(|(id, _)| *id == flow_id) {\n PrepareResult {\n status: \"ok\".into(),\n error: None,\n }\n } else {\n PrepareResult {\n status: \"error\".into(),\n error: Some(format!(\"unknown flow: {flow_id}\")),\n }\n }\n }\n\n fn run_flow(&self, flow_id: &str, input: Value) -> RunResult {\n if let Some((_, source)) = flows().iter().find(|(id, _)| *id == flow_id) {\n RunResult {\n status: \"ok\".into(),\n output: Some(serde_json::json!({\n \"flow_id\": flow_id,\n \"source\": source,\n \"input_echo\": input,\n })),\n error: None,\n }\n } else {\n RunResult {\n status: \"error\".into(),\n output: None,\n error: Some(format!(\"unknown flow: {flow_id}\")),\n }\n }\n }\n\n fn a2a_search(&self, _query: &str) -> Vec<A2AItem> {\n Vec::new()\n }\n}\n\npub fn component() -> Component {\n Component\n}\n\n#[no_mangle]\npub extern \"C\" fn greentic_pack_export__list_flows(json_buffer: *mut u8, len: usize) -> usize {\n let component = Component;\n let flows = component.list_flows();\n write_json_response(&flows, json_buffer, len)\n}\n\n/// # Safety\n///\n/// The caller must ensure that `flow_id_ptr` points to `flow_id_len` bytes of\n/// valid UTF-8 and that `json_buffer` points to a writable region of at least\n/// `len` bytes when non-null.\n#[no_mangle]\npub unsafe extern \"C\" fn greentic_pack_export__prepare_flow(\n flow_id_ptr: *const u8,\n flow_id_len: usize,\n json_buffer: *mut u8,\n len: usize,\n) -> usize {\n let component = Component;\n let flow_id = slice_to_str(flow_id_ptr, flow_id_len);\n let result = component.prepare_flow(flow_id);\n write_json_response(&result, json_buffer, len)\n}\n\n/// # Safety\n///\n/// The caller must ensure that `flow_id_ptr` points to `flow_id_len` bytes of\n/// valid UTF-8 and that `json_buffer` points to a writable region of at least\n/// `len` bytes when non-null.\n#[no_mangle]\npub unsafe extern \"C\" fn greentic_pack_export__run_flow(\n flow_id_ptr: *const u8,\n flow_id_len: usize,\n json_buffer: *mut u8,\n len: usize,\n) -> usize {\n let component = Component;\n let flow_id = slice_to_str(flow_id_ptr, flow_id_len);\n let result = component.run_flow(flow_id, serde_json::Value::Null);\n write_json_response(&result, json_buffer, len)\n}\n\n#[no_mangle]\npub extern \"C\" fn greentic_pack_export__a2a_search(json_buffer: *mut u8, len: usize) -> usize {\n let component = Component;\n let items = component.a2a_search(\"\");\n write_json_response(&items, json_buffer, len)\n}\n\nfn write_json_response<T: serde::Serialize>(value: &T, buffer: *mut u8, len: usize) -> usize {\n let json = serde_json::to_vec(value).expect(\"serialisation succeeds\");\n if buffer.is_null() || len == 0 {\n return json.len();\n }\n\n let copy_len = core::cmp::min(json.len(), len);\n unsafe {\n core::ptr::copy_nonoverlapping(json.as_ptr(), buffer, copy_len);\n }\n copy_len\n}\n\nunsafe fn slice_to_str<\'a>(ptr: *const u8, len: usize) -> &\'a str {\n let bytes = core::slice::from_raw_parts(ptr, len);\n core::str::from_utf8(bytes).expect(\"flow id is valid utf-8\")\n}\n";