1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize};
use tokio::fs;
use tokio::sync::OnceCell;
use url::Url;
use crate::native::{
workspace::Workspace,
ConfigGetCommand, ConfigSetCommand,
};
#[derive(Serialize, Deserialize, Clone)]
pub struct ConfigContents {
pub gateway_url: Option<Url>,
pub counterpart: Option<String>,
pub difftool: Option<String>,
}
pub struct Config<'a> {
workspace: &'a Workspace,
contents: OnceCell<ConfigContents>,
}
impl<'a> From<&'a Workspace> for Config<'a> {
fn from(workspace: &'a Workspace) -> Self {
Config {
workspace,
contents: Default::default(),
}
}
}
impl<'a> Config<'a> {
pub async fn read(&self) -> Result<&ConfigContents> {
self.contents
.get_or_try_init(|| {
let config_path = self.workspace.config_path().clone();
async {
toml_edit::de::from_str(&fs::read_to_string(config_path).await?)
.map_err(|error| anyhow!(error))
}
})
.await
}
pub async fn write(&mut self, contents: &ConfigContents) -> Result<()> {
fs::write(
self.workspace.config_path(),
toml_edit::ser::to_vec(contents)?,
)
.await?;
self.contents = OnceCell::new();
Ok(())
}
}
pub async fn config_set(command: ConfigSetCommand, workspace: &Workspace) -> Result<()> {
workspace.expect_local_directories()?;
let mut config = Config::from(workspace);
let mut config_contents = config.read().await?.clone();
match command {
ConfigSetCommand::GatewayUrl { url } => config_contents.gateway_url = Some(url),
ConfigSetCommand::Counterpart { did } => config_contents.counterpart = Some(did),
ConfigSetCommand::Difftool { tool } => config_contents.difftool = Some(tool),
};
config.write(&config_contents).await?;
Ok(())
}
pub async fn config_get(command: ConfigGetCommand, workspace: &Workspace) -> Result<()> {
workspace.expect_local_directories()?;
let config = Config::from(workspace);
let config_contents = config.read().await?.clone();
let value = match command {
ConfigGetCommand::GatewayUrl => config_contents.gateway_url.map(|url| url.to_string()),
ConfigGetCommand::Counterpart => config_contents.counterpart,
ConfigGetCommand::Difftool => config_contents.difftool,
};
if let Some(value) = value {
println!("{value}");
}
Ok(())
}