[feat] modularized backend with plugin architecture, added module-api, module-host, and summarizer crates, and integrated dynamic module loading into main.rs

This commit is contained in:
2025-08-20 08:51:38 +02:00
parent 7c6724800f
commit 16167d18ff
11 changed files with 420 additions and 10 deletions

View File

@@ -0,0 +1,14 @@
[package]
name = "owly-news-module-summarizer"
version.workspace = true
edition.workspace = true
[lib]
crate-type = ["cdylib"]
path = "src/lib.rs"
[dependencies]
anyhow = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
owly-news-module-api = { path = "../../module-api" }

View File

@@ -0,0 +1,50 @@
use owly_news_module_api::{cstr_to_str, string_to_cstring_ptr};
use serde::{Deserialize, Serialize};
use std::os::raw::c_char;
#[derive(Deserialize)]
struct SummarizeReq {
text: String,
#[serde(default = "default_ratio")]
ratio: f32,
}
fn default_ratio() -> f32 { 0.2 }
#[derive(Serialize)]
struct SummarizeResp {
summary: String,
}
#[unsafe(no_mangle)]
pub extern "C" fn module_name() -> *const c_char {
// IMPORTANT: string must live forever; use a const C string
static NAME: &str = "summarizer\0";
NAME.as_ptr() as *const c_char
}
#[unsafe(no_mangle)]
pub extern "C" fn module_invoke(op: *const c_char, payload: *const c_char) -> *mut c_char {
// SAFETY: called by trusted host with valid pointers
let res = (|| -> anyhow::Result<String> {
let op = unsafe { cstr_to_str(op)? };
let payload = unsafe { cstr_to_str(payload)? };
match op {
"summarize" => {
let req: SummarizeReq = serde_json::from_str(payload)?;
// Placeholder summarization logic. Replace with real algorithm.
let words: Vec<&str> = req.text.split_whitespace().collect();
let take = ((words.len() as f32) * req.ratio).max(1.0).round() as usize;
let summary = words.into_iter().take(take).collect::<Vec<_>>().join(" ");
let resp = SummarizeResp { summary };
Ok(serde_json::to_string(&resp)?)
}
_ => anyhow::bail!("unknown op: {op}"),
}
})();
let json = res.unwrap_or_else(|e| serde_json::json!({ "error": e.to_string() }).to_string());
string_to_cstring_ptr(json)
}