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
94
95
96
97
98
99
100
101
|
use std::path::Path;
use std::path::PathBuf;
use anyhow::Result;
use tokio::io::AsyncReadExt;
use crate::client::Client;
use crate::config::Config;
use crate::ipfs_client::IpfsClient;
#[derive(Debug)]
pub struct Profile {
client: Client,
}
impl Profile {
pub async fn create(state_dir: &Path, name: &str, config: Config) -> Result<Self> {
let bootstrap = vec![]; // TODO
let mdns = false; // TODO
let keypair = ipfs::Keypair::generate_ed25519();
Self::write_to_statedir(state_dir, name, &keypair).await?;
let options = ipfs::IpfsOptions {
ipfs_path: Self::ipfs_path(state_dir, name).await?,
keypair,
bootstrap,
mdns,
kad_protocol: None,
listening_addrs: vec![],
span: Some(tracing::trace_span!("distrox-ipfs")),
};
let (ipfs, fut): (ipfs::Ipfs<_>, _) = ipfs::UninitializedIpfs::<_>::new(options)
.start()
.await?;
tokio::task::spawn(fut);
Ok(Self::new(ipfs, config))
}
async fn new_inmemory(config: Config) -> Result<Self> {
let mut opts = ipfs::IpfsOptions::inmemory_with_generated_keys();
opts.mdns = false;
let (ipfs, fut): (ipfs::Ipfs<_>, _) = ipfs::UninitializedIpfs::<_>::new(opts).start().await.unwrap();
tokio::task::spawn(fut);
Ok(Self::new(ipfs, config))
}
fn new(ipfs: IpfsClient, config: Config) -> Self {
Profile { client: Client::new(ipfs, config) }
}
async fn write_to_statedir(_state_dir: &Path, _name: &str, _keypair: &ipfs::Keypair) -> Result<()> {
unimplemented!()
}
async fn ipfs_path(state_dir: &Path, name: &str) -> Result<PathBuf> {
let path = state_dir.join(name).join("ipfs");
tokio::fs::create_dir_all(&path).await?;
Ok(path)
}
pub fn config_path(name: &str) -> String {
format!("distrox-{}", name)
}
pub fn config_file_path(name: &str) -> Result<PathBuf> {
xdg::BaseDirectories::with_prefix("distrox")
.map_err(anyhow::Error::from)
.and_then(|dirs| {
let name = Self::config_path(name);
dirs.place_config_file(name)
.map_err(anyhow::Error::from)
})
}
/// Load the Profile from disk and ensure the keys exist in IPFS
pub async fn load_from_filesystem(_name: &str, _client: &Client) -> Result<Option<Self>> {
unimplemented!()
}
async fn load_from_reader<R: AsyncReadExt + std::marker::Unpin>(_r: R, _name: &str, _client: &Client) -> Result<Option<Self>> {
unimplemented!()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::client::Client;
use crate::config::Config;
use crate::ipfs_client::IpfsClient;
#[tokio::test]
async fn test_create_profile() {
let _ = env_logger::try_init();
let profile = Profile::new_inmemory(Config::default()).await;
assert!(profile.is_ok());
}
}
|