Skip to content

Commit

Permalink
CLEO -> Introduce structure for parsing types via FromStr.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbfm committed Apr 29, 2024
1 parent f1933f4 commit 2ef16cd
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 10 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions opendut-cleo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ glob = { workspace = true }
indoc = { workspace = true }
serde_json = { workspace = true }
shadow-rs = { workspace = true, default-features = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tonic = { workspace = true, features = ["tls"] }
uuid = { workspace = true, features = ["v4"] }
Expand Down
27 changes: 17 additions & 10 deletions opendut-cleo/src/commands/cluster_configuration/create.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
use std::collections::HashSet;
use std::ops::Not;

use uuid::Uuid;

use opendut_carl_api::carl::CarlClient;
use opendut_types::cluster::{ClusterConfiguration, ClusterId, ClusterName};
use opendut_types::cluster::{ClusterConfiguration, ClusterId};
use opendut_types::peer::PeerId;
use opendut_types::topology::{DeviceDescriptor, DeviceName};

use crate::{ClusterConfigurationDevices, CreateOutputFormat};
use crate::parse::cluster::{ParseableClusterId, ParseableClusterName};

/// Create a cluster configuration
#[derive(clap::Parser)]
pub struct CreateClusterConfigurationCli {
///Name of the cluster
#[arg(short, long)]
name: String,
name: ParseableClusterName,
///ClusterID
#[arg(short, long)]
cluster_id: Option<Uuid>,
cluster_id: Option<ParseableClusterId>,
///PeerID of the leader
#[arg(short, long)]
leader_id: Uuid,
Expand All @@ -30,11 +34,12 @@ impl CreateClusterConfigurationCli {
carl: &mut CarlClient,
output: CreateOutputFormat,
) -> crate::Result<()> {
let name = ClusterName::try_from(self.name)
.map_err(|cause| format!("Error while creating cluster configuration: {}", cause))?;
let ParseableClusterName(cluster_name) = self.name;

let leader = PeerId::from(self.leader_id); //TODO: check if peer exists
let cluster_id = ClusterId::from(self.cluster_id.unwrap_or_else(Uuid::new_v4));
let cluster_id = self.cluster_id
.map(|ParseableClusterId(id)| id)
.unwrap_or_else(ClusterId::random);

let all_devices = carl.peers.list_devices().await
.map_err(|error| format!("Error while listing devices.\n {}", error))?;
Expand All @@ -57,16 +62,16 @@ impl CreateClusterConfigurationCli {
Err("Specify at least 2 devices per cluster configuration.".to_string())?
}

let configuration = ClusterConfiguration { id: cluster_id, name: Clone::clone(&name), leader, devices: device_ids };
let configuration = ClusterConfiguration { id: cluster_id, name: Clone::clone(&cluster_name), leader, devices: device_ids };
carl.cluster.store_cluster_configuration(configuration.clone()).await
.map_err(|err| format!("Could not store cluster configuration. Make sure the application is running. Error: {}", err))?;

match output {
CreateOutputFormat::Text => {
println!("Successfully stored new cluster configuration.");

println!("ClusterID: {:?}", cluster_id);
println!("Name of the Cluster: {:?}", name);
println!("ClusterID: {}", cluster_id);
println!("Name of the Cluster: {}", cluster_name);
println!("The following devices are part of the cluster configuration:");
for device_name in device_names.iter() {
println!("\x09{}", device_name);
Expand Down Expand Up @@ -127,12 +132,14 @@ fn check_devices(all_devices: &[DeviceDescriptor], device_names: &[DeviceName],

#[cfg(test)]
mod test {
use super::*;
use googletest::prelude::*;
use rstest::{fixture, rstest};

use opendut_types::topology::{DeviceDescription, DeviceId, DeviceName};
use opendut_types::util::net::{NetworkInterfaceConfiguration, NetworkInterfaceDescriptor, NetworkInterfaceName};

use super::*;

#[fixture]
fn all_devices() -> Vec<DeviceDescriptor> {
vec![
Expand Down
1 change: 1 addition & 0 deletions opendut-cleo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use opendut_types::topology::DeviceName;
use opendut_util::settings::{FileFormat, load_config};

mod commands;
pub mod parse;

type Error = String;
type Result<T> = std::result::Result<T, Error>;
Expand Down
27 changes: 27 additions & 0 deletions opendut-cleo/src/parse/cluster.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use opendut_types::cluster::*;

use super::*;

#[derive(Clone)]
pub struct ParseableClusterId(pub ClusterId);
impl FromStr for ParseableClusterId {
type Err = ParseError;

fn from_str(value: &str) -> Result<Self, Self::Err> {
let inner = ClusterId::try_from(value)
.map_err(|cause| ParseError::new::<Self>(value, cause.to_string()))?;
Ok(Self(inner))
}
}

#[derive(Clone)]
pub struct ParseableClusterName(pub ClusterName);
impl FromStr for ParseableClusterName {
type Err = ParseError;

fn from_str(value: &str) -> Result<Self, Self::Err> {
let inner = ClusterName::try_from(value)
.map_err(|cause| ParseError::new::<Self>(value, cause.to_string()))?;
Ok(Self(inner))
}
}
22 changes: 22 additions & 0 deletions opendut-cleo/src/parse/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pub mod cluster;

use std::str::FromStr;


#[derive(thiserror::Error, Debug, Eq, PartialEq)]
#[error("Could not parse '{from}' as {to}: {details}")]
pub struct ParseError {
from: String,
to: &'static str,
details: String,
}

impl ParseError {
pub fn new<To>(from: impl Into<String>, details: impl Into<String>) -> Self {
Self {
from: from.into(),
to: std::any::type_name::<To>(),
details: details.into(),
}
}
}

0 comments on commit 2ef16cd

Please sign in to comment.