wire/answer/devices.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4// Copyright (c) 2026 2youg1 and the sprawling contributors
5
6//! The browsers paired at this machine's door
7//! (`crates/wire/spec/Answer/Devices.lean` ยง8-91).
8
9use kernel::TimeMs;
10use serde::{Deserialize, Serialize};
11
12/// Every paired browser.
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
15pub struct DevicesAnswer {
16 pub devices: Vec<DeviceLine>,
17}
18
19/// One paired browser, as a person recognises and revokes it. Its public
20/// key and its sessions stay in the city.
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
23pub struct DeviceLine {
24 pub id: DeviceId,
25 /// The name the page gave when it paired.
26 pub label: String,
27 pub paired_at: TimeMs,
28 /// The last time it opened a session; absent until it has.
29 pub last_seen: Option<TimeMs>,
30}
31
32/// A paired browser, by the id the city gave it when it paired.
33///
34/// The text as the city wrote it; the wire does not read it. An id the
35/// city does not know and a misspelt one get the same refusal, because for
36/// the door both mean there is no such device.
37#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
38#[serde(transparent)]
39#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
40pub struct DeviceId(String);
41
42impl DeviceId {
43 /// The id as the city wrote it.
44 #[must_use]
45 pub fn new(text: String) -> Self {
46 Self(text)
47 }
48
49 #[must_use]
50 pub fn as_str(&self) -> &str {
51 &self.0
52 }
53}