duende_platform/
adapter.rs

1//! Platform adapter trait.
2//!
3//! # Toyota Way: Standardized Work (標準作業)
4//! Every platform follows the same adapter contract.
5
6use async_trait::async_trait;
7
8use duende_core::{Daemon, DaemonStatus, Signal};
9
10use crate::detect::Platform;
11use crate::error::Result;
12
13/// Handle to a running daemon.
14#[derive(Debug, Clone)]
15pub struct DaemonHandle {
16    /// Platform that spawned this daemon.
17    pub platform: Platform,
18    /// Platform-specific identifier.
19    pub id: String,
20    /// Process ID (if applicable).
21    pub pid: Option<u32>,
22}
23
24impl DaemonHandle {
25    /// Creates a native daemon handle.
26    #[must_use]
27    pub fn native(pid: u32) -> Self {
28        Self {
29            platform: Platform::Native,
30            id: pid.to_string(),
31            pid: Some(pid),
32        }
33    }
34
35    /// Creates a systemd daemon handle.
36    #[must_use]
37    pub fn systemd(unit_name: impl Into<String>) -> Self {
38        Self {
39            platform: Platform::Linux,
40            id: unit_name.into(),
41            pid: None,
42        }
43    }
44
45    /// Creates a launchd daemon handle.
46    #[must_use]
47    pub fn launchd(label: impl Into<String>) -> Self {
48        Self {
49            platform: Platform::MacOS,
50            id: label.into(),
51            pid: None,
52        }
53    }
54
55    /// Creates a container daemon handle.
56    #[must_use]
57    pub fn container(container_id: impl Into<String>) -> Self {
58        Self {
59            platform: Platform::Container,
60            id: container_id.into(),
61            pid: None,
62        }
63    }
64
65    /// Creates a pepita daemon handle.
66    #[must_use]
67    pub fn pepita(vm_id: impl Into<String>) -> Self {
68        Self {
69            platform: Platform::PepitaMicroVM,
70            id: vm_id.into(),
71            pid: None,
72        }
73    }
74
75    /// Creates a WOS daemon handle.
76    #[must_use]
77    pub fn wos(process_id: u32) -> Self {
78        Self {
79            platform: Platform::Wos,
80            id: process_id.to_string(),
81            pid: Some(process_id),
82        }
83    }
84}
85
86/// Handle to an attached tracer.
87#[derive(Debug)]
88pub struct TracerHandle {
89    /// Platform that owns this tracer.
90    pub platform: Platform,
91    /// Tracer identifier.
92    pub id: String,
93}
94
95/// Platform-specific daemon adapter.
96///
97/// Each platform implements this trait to provide daemon lifecycle
98/// management in a platform-appropriate way.
99#[async_trait]
100pub trait PlatformAdapter: Send + Sync {
101    /// Returns the platform this adapter supports.
102    fn platform(&self) -> Platform;
103
104    /// Spawns a daemon on this platform.
105    ///
106    /// # Errors
107    /// Returns an error if spawning fails.
108    async fn spawn(&self, daemon: Box<dyn Daemon>) -> Result<DaemonHandle>;
109
110    /// Sends a signal to a daemon.
111    ///
112    /// # Errors
113    /// Returns an error if signaling fails.
114    async fn signal(&self, handle: &DaemonHandle, sig: Signal) -> Result<()>;
115
116    /// Queries the status of a daemon.
117    ///
118    /// # Errors
119    /// Returns an error if status query fails.
120    async fn status(&self, handle: &DaemonHandle) -> Result<DaemonStatus>;
121
122    /// Attaches a tracer to a daemon (renacer integration).
123    ///
124    /// # Errors
125    /// Returns an error if tracer attachment fails.
126    async fn attach_tracer(&self, handle: &DaemonHandle) -> Result<TracerHandle>;
127}