artifactize_core/store/definitions/
extensions.rs1use crate::{config::StoredProfile, project::selection::Selection};
3use serde::{Deserialize, Deserializer, Serialize, Serializer, ser::SerializeMap};
4use serde_json::{Map, Value};
5use std::collections::BTreeMap;
6
7#[derive(Debug, Clone)]
8pub struct Profile {
9 pub known: StoredProfile,
10 pub extra: Map<String, Value>,
11}
12impl<'de> Deserialize<'de> for Profile {
13 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
14 let mut fields = Map::<String, Value>::deserialize(deserializer)?;
15 let names: &[&str] = match fields.get("kind").and_then(Value::as_str) {
16 Some("agent") => &[
17 "kind",
18 "backend",
19 "model",
20 "reasoning",
21 "timeoutMs",
22 "maxToolCalls",
23 "maxTokens",
24 ],
25 Some("runtime") => &["kind", "command", "args", "timeoutMs"],
26 _ => &["kind"],
27 };
28 let known = split(&mut fields, names);
29 let known =
30 serde_json::from_value(Value::Object(known)).map_err(serde::de::Error::custom)?;
31 Ok(Self {
32 known,
33 extra: fields,
34 })
35 }
36}
37impl Serialize for Profile {
38 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
39 serialize(&self.known, &self.extra, serializer)
40 }
41}
42
43#[derive(Debug, Clone)]
44pub struct SavedSelection {
45 pub known: Selection,
46 pub extra: Map<String, Value>,
47}
48impl<'de> Deserialize<'de> for SavedSelection {
49 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
50 let mut fields = Map::<String, Value>::deserialize(deserializer)?;
51 let names: &[&str] = match fields.get("kind").and_then(Value::as_str) {
52 Some("artifact") => &["kind", "artifactId"],
53 Some("eval") => &["kind", "evalId"],
54 Some("artifacts") => &["kind", "artifactIds"],
55 Some("evals") => &["kind", "evalIds"],
56 _ => &["kind"],
57 };
58 let known = serde_json::from_value(Value::Object(split(&mut fields, names)))
59 .map_err(serde::de::Error::custom)?;
60 Ok(Self {
61 known,
62 extra: fields,
63 })
64 }
65}
66impl Serialize for SavedSelection {
67 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
68 serialize(&self.known, &self.extra, serializer)
69 }
70}
71fn split(fields: &mut Map<String, Value>, names: &[&str]) -> Map<String, Value> {
72 names
73 .iter()
74 .filter_map(|name| fields.remove(*name).map(|value| ((*name).into(), value)))
75 .collect()
76}
77fn serialize<T: Serialize, S: Serializer>(
78 known: &T,
79 extra: &Map<String, Value>,
80 serializer: S,
81) -> Result<S::Ok, S::Error> {
82 let known: BTreeMap<String, Value> =
83 serde_json::from_value(serde_json::to_value(known).map_err(serde::ser::Error::custom)?)
84 .map_err(serde::ser::Error::custom)?;
85 let mut object = serializer.serialize_map(Some(known.len() + extra.len()))?;
86 for (name, value) in known {
87 object.serialize_entry(&name, &value)?;
88 }
89 for (name, value) in extra {
90 object.serialize_entry(name, value)?;
91 }
92 object.end()
93}