agent_first_http/sdk/profile/
meta.rs1use std::time::SystemTime;
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ProfileMeta {
9 pub schema_version: u32,
10 pub name: String,
11 pub backend: String,
12 pub created_at_rfc3339: String,
13 pub last_used_at_rfc3339: String,
14 pub last_host_version: String,
15}
16
17impl ProfileMeta {
18 pub const SCHEMA_VERSION: u32 = 2;
19
20 pub fn new(name: impl Into<String>, backend: impl Into<String>) -> Self {
21 let now = now_rfc3339();
22 Self {
23 schema_version: Self::SCHEMA_VERSION,
24 name: name.into(),
25 backend: backend.into(),
26 created_at_rfc3339: now.clone(),
27 last_used_at_rfc3339: now,
28 last_host_version: env!("CARGO_PKG_VERSION").to_string(),
29 }
30 }
31
32 pub fn touch_for_host(mut self) -> Self {
33 self.schema_version = Self::SCHEMA_VERSION;
34 self.last_used_at_rfc3339 = now_rfc3339();
35 self.last_host_version = env!("CARGO_PKG_VERSION").to_string();
36 self
37 }
38}
39
40pub fn now_rfc3339() -> String {
42 humantime::format_rfc3339_seconds(SystemTime::now()).to_string()
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn now_rfc3339_is_second_precision_utc() {
51 let s = now_rfc3339();
52 assert!(s.ends_with('Z'));
53 assert_eq!(s.len(), 20); }
55
56 #[test]
57 fn meta_round_trips_through_json() {
58 let m = ProfileMeta::new("work", "brave");
59 let s = serde_json::to_string(&m).unwrap_or_default();
60 let back: ProfileMeta = serde_json::from_str(&s).unwrap();
61 assert_eq!(back.name, "work");
62 assert_eq!(back.backend, "brave");
63 assert_eq!(back.schema_version, ProfileMeta::SCHEMA_VERSION);
64 }
65}