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;