1use crate::load::LoadSpec;
2use serde::{Deserialize, Serialize};
3use std::path::Path;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct EnvSpec {
7 pub name: String,
8 pub instances: Vec<EnvInstanceSpec>,
9 #[serde(default)]
10 pub can_buses: Vec<EnvCanBusSpec>,
11 #[serde(default)]
12 pub shared_channels: Vec<EnvSharedChannelSpec>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct EnvInstanceSpec {
17 pub name: String,
18 pub load_spec: LoadSpec,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct EnvCanBusSpec {
23 pub name: String,
24 pub vcan_iface: String,
25 #[serde(default)]
26 pub dbc_path: Option<String>,
27 #[serde(default)]
28 pub members: Vec<EnvCanBusMemberSpec>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct EnvCanBusMemberSpec {
33 pub instance_name: String,
34 pub bus_name: String,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct EnvSharedChannelSpec {
39 pub name: String,
40 pub writer_instance: String,
41 #[serde(default)]
42 pub members: Vec<EnvSharedChannelMemberSpec>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct EnvSharedChannelMemberSpec {
47 pub instance_name: String,
48 pub channel_name: String,
49}
50
51pub fn read_env_spec(path: &Path) -> Result<EnvSpec, String> {
52 let content = std::fs::read_to_string(path)
53 .map_err(|err| format!("failed to read env spec '{}': {err}", path.display()))?;
54 serde_json::from_str(&content)
55 .map_err(|err| format!("invalid env spec json '{}': {err}", path.display()))
56}
57
58pub fn write_env_spec(path: &Path, spec: &EnvSpec) -> Result<(), String> {
59 let content = serde_json::to_string(spec)
60 .map_err(|err| format!("failed to serialize env spec '{}': {err}", path.display()))?;
61 std::fs::write(path, content)
62 .map_err(|err| format!("failed to write env spec '{}': {err}", path.display()))
63}