Skip to main content

ahp_types/
common.rs

1//! Hand-written primitives that the code generator relies on.
2//!
3//! The generator emits strongly typed Rust counterparts for all TypeScript
4//! interfaces and enums into `state.rs`, `actions.rs`, `commands.rs`,
5//! `notifications.rs`, and `messages.rs`. This file contains the small set of
6//! bespoke shapes the generator cannot express as a plain struct.
7
8use serde::{Deserialize, Serialize};
9
10/// A URI string, e.g. `ahp-root://` or `ahp-session:/<uuid>`.
11pub type Uri = String;
12
13/// Well-known channel URI for the root channel.
14///
15/// Subscribe to this URI to receive [`crate::state::RootState`] snapshots
16/// and root-level actions (agents changed, active sessions changed,
17/// terminals changed, config changed). Always present on every host.
18pub const ROOT_RESOURCE_URI: &str = "ahp-root://";
19
20/// A string that may optionally be rendered as Markdown.
21///
22/// Serialized as either a plain JSON string or `{ "markdown": "..." }`.
23#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
24#[serde(untagged)]
25pub enum StringOrMarkdown {
26    /// Plain text rendered verbatim.
27    Plain(String),
28    /// Markdown-rendered object `{ "markdown": "..." }`.
29    Markdown {
30        /// Markdown source.
31        markdown: String,
32    },
33}
34
35impl Default for StringOrMarkdown {
36    fn default() -> Self {
37        Self::Plain(String::new())
38    }
39}
40
41impl StringOrMarkdown {
42    /// Returns the raw text regardless of kind.
43    pub fn as_text(&self) -> &str {
44        match self {
45            Self::Plain(s) => s,
46            Self::Markdown { markdown } => markdown,
47        }
48    }
49
50    /// Append plain text to the underlying content.
51    pub fn push_str(&mut self, more: &str) {
52        match self {
53            Self::Plain(s) => s.push_str(more),
54            Self::Markdown { markdown } => markdown.push_str(more),
55        }
56    }
57}
58
59impl From<String> for StringOrMarkdown {
60    fn from(s: String) -> Self {
61        Self::Plain(s)
62    }
63}
64
65impl From<&str> for StringOrMarkdown {
66    fn from(s: &str) -> Self {
67        Self::Plain(s.to_owned())
68    }
69}
70
71/// Type alias for a JSON object. Used for `_meta`, `structuredContent`, and
72/// other `Record<string, unknown>` fields.
73pub type JsonObject = serde_json::Map<String, serde_json::Value>;
74
75/// Opaque JSON value (the Rust counterpart to the TypeScript `unknown` type).
76pub type AnyValue = serde_json::Value;