Skip to main content

aver_rt/
service_types.rs

1use crate::{AverDisplay, AverList, AverMap, AverStr};
2
3#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
4pub struct TerminalSize {
5    pub width: i64,
6    pub height: i64,
7}
8
9impl AverDisplay for TerminalSize {
10    fn aver_display(&self) -> String {
11        format!(
12            "Terminal.Size(width: {}, height: {})",
13            self.width.aver_display_inner(),
14            self.height.aver_display_inner()
15        )
16    }
17
18    fn aver_display_inner(&self) -> String {
19        self.aver_display()
20    }
21}
22
23/// Multi-value HTTP headers, modelled as `Map<String, List<String>>` —
24/// matches RFC 9110 (same-name fields) and RFC 6265 (multiple
25/// Set-Cookie). Keys are case-insensitive by convention; runtime
26/// lowercases incoming names. Mirrors Go `net/http.Header`.
27pub type HttpHeaders = AverMap<AverStr, AverList<AverStr>>;
28
29#[derive(Clone, Debug, PartialEq)]
30pub struct HttpResponse {
31    pub status: i64,
32    pub body: AverStr,
33    pub headers: HttpHeaders,
34}
35
36impl AverDisplay for HttpResponse {
37    fn aver_display(&self) -> String {
38        format!(
39            "HttpResponse(status: {}, body: {}, headers: {})",
40            self.status.aver_display_inner(),
41            self.body.aver_display_inner(),
42            self.headers.aver_display_inner()
43        )
44    }
45
46    fn aver_display_inner(&self) -> String {
47        self.aver_display()
48    }
49}
50
51#[derive(Clone, Debug, PartialEq)]
52pub struct HttpRequest {
53    pub method: AverStr,
54    pub path: AverStr,
55    pub body: AverStr,
56    pub headers: HttpHeaders,
57}
58
59impl AverDisplay for HttpRequest {
60    fn aver_display(&self) -> String {
61        format!(
62            "HttpRequest(method: {}, path: {}, body: {}, headers: {})",
63            self.method.aver_display_inner(),
64            self.path.aver_display_inner(),
65            self.body.aver_display_inner(),
66            self.headers.aver_display_inner()
67        )
68    }
69
70    fn aver_display_inner(&self) -> String {
71        self.aver_display()
72    }
73}
74
75#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
76pub struct TcpConnection {
77    pub id: AverStr,
78    pub host: AverStr,
79    pub port: i64,
80}
81
82impl TcpConnection {
83    pub fn from_parts(id: String, host: String, port: i64) -> Self {
84        Self {
85            id: AverStr::from(id),
86            host: AverStr::from(host),
87            port,
88        }
89    }
90}
91
92impl AverDisplay for TcpConnection {
93    fn aver_display(&self) -> String {
94        format!(
95            "Tcp.Connection(id: {}, host: {}, port: {})",
96            self.id.aver_display_inner(),
97            self.host.aver_display_inner(),
98            self.port.aver_display_inner()
99        )
100    }
101
102    fn aver_display_inner(&self) -> String {
103        self.aver_display()
104    }
105}
106
107/// `BranchPath` — opaque dewey-decimal identifier for a branch in the
108/// structural tree of `!`/`?!` groups. In the VM/interpreter it is a
109/// built-in record `{ dewey: String }`; it surfaces in source only as
110/// the first parameter of Oracle-proof stub functions
111/// (`oracle : (BranchPath, Int, args...) -> T`). Those stub fns are
112/// emitted by the Rust backend as ordinary (dead-at-runtime) functions
113/// because module-level fns are emitted regardless of reachability, so
114/// the type must be in scope for them to compile. It is never produced
115/// or consumed by runtime code — only `aver verify` exercises the
116/// Oracle laws — so the constructors here only need to compile.
117#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
118pub struct BranchPath {
119    pub dewey: AverStr,
120}
121
122impl BranchPath {
123    /// Canonical root path (empty dewey). Mirrors `BranchPath.Root` in
124    /// `src/types/branch_path.rs`.
125    pub fn root() -> Self {
126        Self {
127            dewey: AverStr::from(""),
128        }
129    }
130
131    /// Extend a path by entering branch `idx` of a group. Mirrors
132    /// `BranchPath.child` (dewey segments joined with `.`).
133    pub fn child(path: &BranchPath, idx: i64) -> Self {
134        let dewey = if path.dewey.is_empty() {
135            idx.to_string()
136        } else {
137            format!("{}.{}", &*path.dewey, idx)
138        };
139        Self {
140            dewey: AverStr::from(dewey),
141        }
142    }
143
144    /// Parse a dewey-decimal path string. Mirrors `BranchPath.parse`.
145    pub fn parse(raw: &str) -> Self {
146        Self {
147            dewey: AverStr::from(raw),
148        }
149    }
150}
151
152impl AverDisplay for BranchPath {
153    fn aver_display(&self) -> String {
154        format!("BranchPath({})", self.dewey.aver_display_inner())
155    }
156
157    fn aver_display_inner(&self) -> String {
158        self.aver_display()
159    }
160}