diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-12-06 16:44:01 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-12-06 16:44:01 +0100 |
commit | deb68740a3cbefa96f26c1197f344b45d1ac55d0 (patch) | |
tree | 8d1087f72890c66d55a5e1e1b3ca7bcb229e94cc /src | |
parent | f0d12775a583ecc7ad6b7b1d215a09c4b9ab8dbf (diff) |
Split profile module into smaller submodules
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/profile/mod.rs (renamed from src/profile.rs) | 126 | ||||
-rw-r--r-- | src/profile/state.rs | 129 |
2 files changed, 135 insertions, 120 deletions
diff --git a/src/profile.rs b/src/profile/mod.rs index 205f3b4..7078adb 100644 --- a/src/profile.rs +++ b/src/profile/mod.rs @@ -1,17 +1,16 @@ -use std::path::Path; use std::path::PathBuf; -use std::convert::TryFrom; use std::convert::TryInto; use anyhow::Context; use anyhow::Result; -use tokio::io::AsyncReadExt; -use tokio::io::AsyncWriteExt; use crate::client::Client; use crate::config::Config; use crate::ipfs_client::IpfsClient; +mod state; +use state::*; + #[derive(Debug)] pub struct Profile { state: ProfileState, @@ -54,11 +53,7 @@ impl Profile { async fn new(ipfs: IpfsClient, config: Config, profile_name: String, keypair: libp2p::identity::Keypair) -> Result<Self> { let client = Client::new(ipfs, config); let profile_head = Self::post_hello_world(&client, &profile_name).await?; - let state = ProfileState { - profile_head, - profile_name, - keypair, - }; + let state = ProfileState::new(profile_head, profile_name, keypair); Ok(Profile { state, client }) } @@ -101,7 +96,7 @@ impl Profile { } pub async fn save(&self) -> Result<()> { - let state_dir_path = Self::state_dir_path(&self.state.profile_name)?; + let state_dir_path = Self::state_dir_path(self.state.profile_name())?; log::trace!("Saving to {:?}", state_dir_path.display()); ProfileStateSaveable::new(&self.state) .context("Serializing profile state")? @@ -122,7 +117,7 @@ impl Profile { let bootstrap = vec![]; // TODO let mdns = false; // TODO - let keypair = state.keypair.clone(); + let keypair = state.keypair().clone(); log::debug!("Configuring IPFS backend"); let options = ipfs::IpfsOptions { @@ -154,115 +149,6 @@ impl Profile { } -#[derive(Debug)] -pub struct StateDir(PathBuf); - -impl StateDir { - pub fn ipfs(&self) -> PathBuf { - self.0.join("ipfs") - } - - pub fn profile_state(&self) -> PathBuf { - self.0.join("profile_state") - } - - pub fn display(&self) -> std::path::Display { - self.0.display() - } -} - -impl From<PathBuf> for StateDir { - fn from(p: PathBuf) -> Self { - Self(p) - } -} - -#[derive(getset::Getters)] -pub struct ProfileState { - #[getset(get = "pub")] - profile_head: cid::Cid, - - #[getset(get = "pub")] - profile_name: String, - - #[getset(get = "pub")] - keypair: libp2p::identity::Keypair, -} - -impl std::fmt::Debug for ProfileState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "ProfileState {{ name = {}, head = {:?} }}", self.profile_name, self.profile_head) - } -} - -#[derive(Debug, serde::Serialize, serde::Deserialize, getset::Getters)] -struct ProfileStateSaveable { - profile_head: Vec<u8>, - profile_name: String, - keypair: Vec<u8>, -} - -impl ProfileStateSaveable { - fn new(s: &ProfileState) -> Result<Self> { - Ok(Self { - profile_head: s.profile_head.to_bytes(), - profile_name: s.profile_name.clone(), - keypair: match s.keypair { - libp2p::identity::Keypair::Ed25519(ref kp) => Vec::from(kp.encode()), - _ => anyhow::bail!("Only keypair type ed25519 supported"), - } - }) - } - - pub async fn save_to_disk(&self, state_dir_path: &StateDir) -> Result<()> { - let state_s = serde_json::to_string(&self).context("Serializing state")?; - tokio::fs::OpenOptions::new() - .create_new(false) // do not _always_ create a new file - .create(true) - .truncate(true) - .write(true) - .open(&state_dir_path.profile_state()) - .await - .with_context(|| format!("Opening {}", state_dir_path.profile_state().display()))? - .write_all(state_s.as_bytes()) - .await - .map(|_| ()) - .with_context(|| format!("Writing to {}", state_dir_path.profile_state().display())) - .map_err(anyhow::Error::from) - } - - pub async fn load_from_disk(state_dir_path: &StateDir) -> Result<Self> { - log::trace!("Loading from disk: {:?}", state_dir_path.profile_state().display()); - let reader = tokio::fs::OpenOptions::new() - .read(true) - .open(&state_dir_path.profile_state()) - .await - .context("Opening state file")? - .into_std() - .await; - - log::trace!("Parsing state file"); - serde_json::from_reader(reader) - .context("Parsing state file") - .map_err(anyhow::Error::from) - } - -} - -impl TryInto<ProfileState> for ProfileStateSaveable { - type Error = anyhow::Error; - - fn try_into(mut self) -> Result<ProfileState> { - Ok(ProfileState { - profile_head: cid::Cid::try_from(self.profile_head)?, - profile_name: self.profile_name, - keypair: { - let kp = libp2p::identity::ed25519::Keypair::decode(&mut self.keypair)?; - libp2p::identity::Keypair::Ed25519(kp) - }, - }) - } -} #[cfg(test)] mod tests { diff --git a/src/profile/state.rs b/src/profile/state.rs new file mode 100644 index 0000000..a84ff23 --- /dev/null +++ b/src/profile/state.rs @@ -0,0 +1,129 @@ +use std::path::PathBuf; +use std::convert::TryFrom; +use std::convert::TryInto; + +use anyhow::Context; +use anyhow::Result; +use tokio::io::AsyncWriteExt; + +#[derive(Debug)] +pub struct StateDir(PathBuf); + +impl StateDir { + pub fn ipfs(&self) -> PathBuf { + self.0.join("ipfs") + } + + pub fn profile_state(&self) -> PathBuf { + self.0.join("profile_state") + } + + pub fn display(&self) -> std::path::Display { + self.0.display() + } +} + +impl From<PathBuf> for StateDir { + fn from(p: PathBuf) -> Self { + Self(p) + } +} + +#[derive(getset::Getters)] +pub struct ProfileState { + #[getset(get = "pub")] + profile_head: cid::Cid, + + #[getset(get = "pub")] + profile_name: String, + + #[getset(get = "pub")] + keypair: libp2p::identity::Keypair, +} + +impl ProfileState { + pub(super) fn new(profile_head: cid::Cid, profile_name: String, keypair: libp2p::identity::Keypair) -> Self { + Self { + profile_head, + profile_name, + keypair + } + } +} + +impl std::fmt::Debug for ProfileState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ProfileState {{ name = {}, head = {:?} }}", self.profile_name, self.profile_head) + } +} + +#[derive(Debug, serde::Serialize, serde::Deserialize, getset::Getters)] +pub(super) struct ProfileStateSaveable { + profile_head: Vec<u8>, + profile_name: String, + keypair: Vec<u8>, +} + +impl ProfileStateSaveable { + pub(super) fn new(s: &ProfileState) -> Result<Self> { + Ok(Self { + profile_head: s.profile_head.to_bytes(), + profile_name: s.profile_name.clone(), + keypair: match s.keypair { + libp2p::identity::Keypair::Ed25519(ref kp) => Vec::from(kp.encode()), + _ => anyhow::bail!("Only keypair type ed25519 supported"), + } + }) + } + + pub async fn save_to_disk(&self, state_dir_path: &StateDir) -> Result<()> { + let state_s = serde_json::to_string(&self).context("Serializing state")?; + tokio::fs::OpenOptions::new() + .create_new(false) // do not _always_ create a new file + .create(true) + .truncate(true) + .write(true) + .open(&state_dir_path.profile_state()) + .await + .with_context(|| format!("Opening {}", state_dir_path.profile_state().display()))? + .write_all(state_s.as_bytes()) + .await + .map(|_| ()) + .with_context(|| format!("Writing to {}", state_dir_path.profile_state().display())) + .map_err(anyhow::Error::from) + } + + pub async fn load_from_disk(state_dir_path: &StateDir) -> Result<Self> { + log::trace!("Loading from disk: {:?}", state_dir_path.profile_state().display()); + let reader = tokio::fs::OpenOptions::new() + .read(true) + .open(&state_dir_path.profile_state()) + .await + .context("Opening state file")? + .into_std() + .await; + + log::trace!("Parsing state file"); + serde_json::from_reader(reader) + .context("Parsing state file") + .map_err(anyhow::Error::from) + } + +} + +impl TryInto<ProfileState> for ProfileStateSaveable { + type Error = anyhow::Error; + + fn try_into(mut self) -> Result<ProfileState> { + Ok(ProfileState { + profile_head: cid::Cid::try_from(self.profile_head)?, + profile_name: self.profile_name, + keypair: { + let kp = libp2p::identity::ed25519::Keypair::decode(&mut self.keypair)?; + libp2p::identity::Keypair::Ed25519(kp) + }, + }) + } +} + + |