refactor(plugins): reorganize Rust output structure to follow standard conventions

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan 2025-12-30 16:53:06 -05:00
parent e2d0c5626c
commit 2b2b673581
13 changed files with 70 additions and 37 deletions

View File

@ -228,11 +228,11 @@ type ServiceB interface {
Expect(string(pyClientActual)).To(Equal(pyClientExpected), "Python client code mismatch")
// Verify Rust client code (now in $output/rust/nd-pdk-host/)
rustHostDir := filepath.Join(outputDir, "rust", "nd-pdk-host")
rsClientEntries, err := os.ReadDir(rustHostDir)
// Verify Rust client code (now in $output/rust/nd-pdk-host/src/)
rustSrcDir := filepath.Join(outputDir, "rust", "nd-pdk-host", "src")
rsClientEntries, err := os.ReadDir(rustSrcDir)
Expect(err).ToNot(HaveOccurred())
Expect(rsClientEntries).To(HaveLen(2), "Expected Rust client file and lib.rs")
Expect(rsClientEntries).To(HaveLen(2), "Expected Rust client file and lib.rs in src/")
// Find the client file (not lib.rs)
var rsClientName string
@ -244,7 +244,7 @@ type ServiceB interface {
}
Expect(rsClientName).ToNot(BeEmpty(), "Expected to find Rust client file")
rsClientActual, err := os.ReadFile(filepath.Join(rustHostDir, rsClientName))
rsClientActual, err := os.ReadFile(filepath.Join(rustSrcDir, rsClientName))
Expect(err).ToNot(HaveOccurred())
Expect(string(rsClientActual)).To(Equal(rsClientExpected), "Rust client code mismatch")

View File

@ -36,8 +36,12 @@
//! - [`{{.Name | lower}}`] - {{if .Doc}}{{.Doc | firstLine}}{{else}}{{.Name}} service{{end}}
{{- end}}
{{range .Services}}
#[path = "nd_host_{{.Name | lower}}.rs"]
pub mod {{.Name | lower}};
#[doc(hidden)]
mod nd_host_{{.Name | lower}};
/// {{if .Doc}}{{.Doc | firstLine}}{{else}}{{.Name}} host service wrappers.{{end}}
pub mod {{.Name | lower}} {
pub use super::nd_host_{{.Name | lower}}::*;
}
{{end}}
// Re-export commonly used types from extism-pdk for convenience
pub use extism_pdk::Error;

View File

@ -577,17 +577,18 @@ func generateRustClientCode(svc internal.Service, outputDir string, dryRun, verb
return fmt.Errorf("generating code: %w", err)
}
// Rust code goes directly in the output directory
clientFile := filepath.Join(outputDir, "nd_host_"+strings.ToLower(svc.Name)+".rs")
// Rust code goes in src/ subdirectory (standard Rust convention)
srcDir := filepath.Join(outputDir, "src")
clientFile := filepath.Join(srcDir, "nd_host_"+strings.ToLower(svc.Name)+".rs")
if dryRun {
fmt.Printf("=== %s ===\n%s\n", clientFile, code)
return nil
}
// Create output directory if needed
if err := os.MkdirAll(outputDir, 0755); err != nil {
return fmt.Errorf("creating rust client directory: %w", err)
// Create src directory if needed
if err := os.MkdirAll(srcDir, 0755); err != nil {
return fmt.Errorf("creating rust src directory: %w", err)
}
if err := os.WriteFile(clientFile, code, 0600); err != nil {
@ -607,17 +608,18 @@ func generateRustLibFile(services []internal.Service, outputDir string, dryRun,
return fmt.Errorf("generating lib.rs: %w", err)
}
// lib.rs goes directly in the output directory
libFile := filepath.Join(outputDir, "lib.rs")
// lib.rs goes in src/ subdirectory (standard Rust convention)
srcDir := filepath.Join(outputDir, "src")
libFile := filepath.Join(srcDir, "lib.rs")
if dryRun {
fmt.Printf("=== %s ===\n%s\n", libFile, code)
return nil
}
// Create output directory if needed
if err := os.MkdirAll(outputDir, 0755); err != nil {
return fmt.Errorf("creating rust client directory: %w", err)
// Create src directory if needed
if err := os.MkdirAll(srcDir, 0755); err != nil {
return fmt.Errorf("creating rust src directory: %w", err)
}
if err := os.WriteFile(libFile, code, 0600); err != nil {

View File

@ -67,10 +67,10 @@ impl Scrobbler for WebhookPlugin {
// Build query parameters
let query = format!(
"?title={}&artist={}&album={}&user={}&timestamp={}",
urlencod(&req.track.title),
urlencod(&req.track.artist),
urlencod(&req.track.album),
urlencod(&req.username),
urlencode(&req.track.title),
urlencode(&req.track.artist),
urlencode(&req.track.album),
urlencode(&req.username),
req.timestamp
);
@ -105,7 +105,7 @@ impl Scrobbler for WebhookPlugin {
}
/// Simple URL encoding for query parameters.
fn urlencod(s: &str) -> String {
fn urlencode(s: &str) -> String {
let mut result = String::with_capacity(s.len() * 3);
for c in s.chars() {
match c {

View File

@ -8,7 +8,6 @@ license = "GPL-3.0"
readme = "README.md"
[lib]
path = "lib.rs"
crate-type = ["rlib"]
[dependencies]

View File

@ -40,26 +40,54 @@
//! - [`subsonicapi`] - provides access to Navidrome's Subsonic API from plugins.
//! - [`websocket`] - provides WebSocket communication capabilities for plugins.
#[path = "nd_host_artwork.rs"]
pub mod artwork;
#[doc(hidden)]
mod nd_host_artwork;
/// provides artwork URL generation capabilities for plugins.
pub mod artwork {
pub use super::nd_host_artwork::*;
}
#[path = "nd_host_cache.rs"]
pub mod cache;
#[doc(hidden)]
mod nd_host_cache;
/// provides in-memory TTL-based caching capabilities for plugins.
pub mod cache {
pub use super::nd_host_cache::*;
}
#[path = "nd_host_kvstore.rs"]
pub mod kvstore;
#[doc(hidden)]
mod nd_host_kvstore;
/// provides persistent key-value storage for plugins.
pub mod kvstore {
pub use super::nd_host_kvstore::*;
}
#[path = "nd_host_library.rs"]
pub mod library;
#[doc(hidden)]
mod nd_host_library;
/// provides access to music library metadata for plugins.
pub mod library {
pub use super::nd_host_library::*;
}
#[path = "nd_host_scheduler.rs"]
pub mod scheduler;
#[doc(hidden)]
mod nd_host_scheduler;
/// provides task scheduling capabilities for plugins.
pub mod scheduler {
pub use super::nd_host_scheduler::*;
}
#[path = "nd_host_subsonicapi.rs"]
pub mod subsonicapi;
#[doc(hidden)]
mod nd_host_subsonicapi;
/// provides access to Navidrome's Subsonic API from plugins.
pub mod subsonicapi {
pub use super::nd_host_subsonicapi::*;
}
#[path = "nd_host_websocket.rs"]
pub mod websocket;
#[doc(hidden)]
mod nd_host_websocket;
/// provides WebSocket communication capabilities for plugins.
pub mod websocket {
pub use super::nd_host_websocket::*;
}
// Re-export commonly used types from extism-pdk for convenience
pub use extism_pdk::Error;