Skip to content

Commit

Permalink
Moved location from devices to peers
Browse files Browse the repository at this point in the history
Fixed some warnings and let `cargo ci check` run
  • Loading branch information
mtwardawski committed Jan 30, 2024
1 parent 93e57cd commit b753071
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 100 deletions.
41 changes: 22 additions & 19 deletions opendut-lea/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
pub use licenses::ComponentLicenses;
pub use licenses::get_licenses;
pub use licenses::ComponentLicenses;

#[derive(thiserror::Error, Debug, Clone)]
pub enum ApiError {

#[error("{message}")]
HttpError {
message: String,
},
HttpError { message: String },

#[error("{message}")]
JsonParseError {
message: String,
},
JsonParseError { message: String },
}

mod licenses {
Expand Down Expand Up @@ -50,50 +45,58 @@ mod licenses {
}

pub async fn get_licenses() -> Result<Vec<ComponentLicenses>, ApiError> {

debug!("Requesting licenses.");

let index = {
let licenses_index = http::Request::get("/api/licenses")
.send().await
.send()
.await
.map_err(|cause| ApiError::HttpError {
message: format!("Failed to request the licenses index file due to: {}", cause),
message: format!(
"Failed to request the licenses index file due to: {}",
cause
),
})?
.json::<LicensesIndexJson>().await
.json::<LicensesIndexJson>()
.await
.map_err(|cause| ApiError::JsonParseError {
message: format!("Failed to parse the licenses index file due to: {}", cause),
})?;

[
("carl", format!("/api/licenses/{}", licenses_index.carl)),
("edgar", format!("/api/licenses/{}", licenses_index.edgar)),
("lea", format!("/api/licenses/{}", licenses_index.lea))
("lea", format!("/api/licenses/{}", licenses_index.lea)),
]
};

let mut result = Vec::<ComponentLicenses>::new();
for (name, path) in index {
let licenses = http::Request::get(&path)
.send().await
.send()
.await
.map_err(|cause| ApiError::HttpError {
message: format!("Failed to request the licenses file due to: {}", cause),
})?
.json::<BTreeMap<String, LicenseJsonEntry>>().await
.json::<BTreeMap<String, LicenseJsonEntry>>()
.await
.map_err(|cause| ApiError::HttpError {
message: format!("Failed to parse the licenses file due to: {}", cause),
})?;

let dependencies = licenses.iter()
.map(|(dependency, licenses) | {
let split = dependency.split(" ").collect::<Vec<_>>();
let dependencies = licenses
.iter()
.map(|(dependency, licenses)| {
let split = dependency.split(' ').collect::<Vec<_>>();
let dependency_name = split[0];
let dependency_version = split[1];
ComponentDependencyLicense {
name: String::from(dependency_name),
version: String::from(dependency_version),
licenses: licenses.licenses.clone(),
}
}).collect::<Vec<ComponentDependencyLicense>>();
})
.collect::<Vec<ComponentDependencyLicense>>();

result.push(ComponentLicenses {
name: String::from(name),
Expand Down
62 changes: 26 additions & 36 deletions opendut-lea/src/peers/configurator/components/controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ use tracing::{debug, error, info};

use opendut_types::peer::{PeerDescriptor, PeerId};

use crate::app::{ExpectGlobals, use_app_globals};
use crate::components::{ButtonColor, ButtonSize, ButtonState, ButtonStateSignalProvider, ConfirmationButton, FontAwesomeIcon, IconButton, Toast, use_toaster};
use crate::app::{use_app_globals, ExpectGlobals};
use crate::components::{
use_toaster, ButtonColor, ButtonSize, ButtonState, ButtonStateSignalProvider,
ConfirmationButton, FontAwesomeIcon, IconButton, Toast,
};
use crate::peers::configurator::types::UserPeerConfiguration;
use crate::routing::{navigate_to, WellKnownRoutes};

Expand All @@ -15,7 +18,6 @@ pub fn Controls(
configuration: ReadSignal<UserPeerConfiguration>,
is_valid_peer_configuration: Signal<bool>,
) -> impl IntoView {

view! {
<div class="buttons">
<SavePeerButton configuration is_valid_peer_configuration />
Expand All @@ -29,7 +31,6 @@ fn SavePeerButton(
configuration: ReadSignal<UserPeerConfiguration>,
is_valid_peer_configuration: Signal<bool>,
) -> impl IntoView {

let globals = use_app_globals();
let toaster = use_toaster();

Expand All @@ -45,17 +46,15 @@ fn SavePeerButton(
match result {
Ok(_) => {
debug!("Successfully stored peer: {peer_id}");
toaster.toast(Toast::builder()
.simple("Successfully stored peer configuration.")
.success()
toaster.toast(
Toast::builder()
.simple("Successfully stored peer configuration.")
.success(),
);
}
Err(cause) => {
error!("Failed to create peer <{peer_id}>, due to error: {cause:?}");
toaster.toast(Toast::builder()
.simple("Failed to store peer!")
.error()
);
toaster.toast(Toast::builder().simple("Failed to store peer!").error());
}
}
}
Expand All @@ -69,14 +68,10 @@ fn SavePeerButton(
let button_state = MaybeSignal::derive(move || {
if store_action.pending().get() {
ButtonState::Loading
}
else {
if is_valid_peer_configuration.get() {
ButtonState::Enabled
}
else {
ButtonState::Disabled
}
} else if is_valid_peer_configuration.get() {
ButtonState::Enabled
} else {
ButtonState::Disabled
}
});

Expand All @@ -96,29 +91,24 @@ fn SavePeerButton(

#[component]
fn DeletePeerButton(configuration: ReadSignal<UserPeerConfiguration>) -> impl IntoView {

let globals = use_app_globals();

let delete_action = create_action(move |_: &PeerId| {
async move {
let mut carl = globals.expect_client();
let peer_id = configuration.get_untracked().id;
let result = carl.peers.delete_peer_descriptor(peer_id).await;
match result {
Ok(_) => {
info!("Successfully deleted peer: {}", peer_id);
navigate_to(WellKnownRoutes::PeersOverview);
}
Err(cause) => {
error!("Failed to delete peer <{peer_id}>, due to error: {cause:?}");
}
let delete_action = create_action(move |_: &PeerId| async move {
let mut carl = globals.expect_client();
let peer_id = configuration.get_untracked().id;
let result = carl.peers.delete_peer_descriptor(peer_id).await;
match result {
Ok(_) => {
info!("Successfully deleted peer: {}", peer_id);
navigate_to(WellKnownRoutes::PeersOverview);
}
Err(cause) => {
error!("Failed to delete peer <{peer_id}>, due to error: {cause:?}");
}
}
});

let button_state = delete_action
.pending()
.derive_loading();
let button_state = delete_action.pending().derive_loading();

view! {
<ConfirmationButton
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
use leptos::{component, create_slice, IntoView, RwSignal, view};
use opendut_types::peer::{IllegalLocation, PeerLocation};
use crate::components::{UserInput, UserInputValue};
use crate::peers::configurator::types::UserPeerConfiguration;
use leptos::{component, create_slice, view, IntoView, RwSignal};
use opendut_types::peer::{IllegalLocation, PeerLocation};

#[component]
pub fn PeerLocationInput(
peer_configuration: RwSignal<UserPeerConfiguration>,
) -> impl IntoView {

let (getter, setter) = create_slice(peer_configuration,
|config| {
Clone::clone(&config.location)
},
|config, input| {
config.location = input;
}
pub fn PeerLocationInput(peer_configuration: RwSignal<UserPeerConfiguration>) -> impl IntoView {
let (getter, setter) = create_slice(
peer_configuration,
|config| Clone::clone(&config.location),
|config, input| {
config.location = input;
},
);

let validator = |input: String| {
Expand All @@ -28,11 +24,11 @@ pub fn PeerLocationInput(
UserInputValue::Both(format!("A peer location must be at most {} characters long.", expected), value)
},
IllegalLocation::InvalidStartEndCharacter { value } => {
UserInputValue::Both(format!("The peer location must start or end with following characters: a-z, A-Z, 0-9 and ()."), value)
UserInputValue::Both("The peer location must start or end with following characters: a-z, A-Z, 0-9 and ().".to_string(), value)
},
IllegalLocation::InvalidCharacter { value } => {
UserInputValue::Both(format!("The peer location contains invalid characters. \
Valid characters are a-z, A-Z, 0-9 and -_/.,() and whitespace"), value)
UserInputValue::Both("The peer location contains invalid characters. \
Valid characters are a-z, A-Z, 0-9 and -_/.,() and whitespace".to_string(), value)
},
}
}
Expand All @@ -48,4 +44,4 @@ pub fn PeerLocationInput(
validator=validator
/>
}
}
}
15 changes: 6 additions & 9 deletions opendut-lea/src/peers/configurator/tabs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ pub use devices::DevicesTab;
pub use general::GeneralTab;
pub use setup::SetupTab;

mod general;
mod devices;
mod general;
mod setup;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TabIdentifier {
#[default]
General,
Devices,
Setup,
Expand All @@ -27,12 +28,6 @@ impl TabIdentifier {
}
}

impl Default for TabIdentifier {
fn default() -> Self {
TabIdentifier::General
}
}

impl TryFrom<&str> for TabIdentifier {
type Error = InvalidTabIdentifier;

Expand All @@ -41,7 +36,9 @@ impl TryFrom<&str> for TabIdentifier {
TabIdentifier::GENERAL_STR => Ok(TabIdentifier::General),
TabIdentifier::DEVICES_STR => Ok(TabIdentifier::Devices),
TabIdentifier::SETUP_STR => Ok(TabIdentifier::Setup),
_ => Err(InvalidTabIdentifier { value: String::from(value) }),
_ => Err(InvalidTabIdentifier {
value: String::from(value),
}),
}
}
}
Expand Down
48 changes: 29 additions & 19 deletions opendut-lea/src/peers/configurator/types.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use leptos::{RwSignal, SignalGetUntracked};

use opendut_types::peer::{PeerLocation, PeerDescriptor, PeerId, PeerName};
use opendut_types::peer::{PeerDescriptor, PeerId, PeerLocation, PeerName};
use opendut_types::topology::{DeviceDescriptor, DeviceId, Topology};
use opendut_types::util::net::NetworkInterfaceName;

use crate::components::UserInputValue;

pub const EMPTY_DEVICE_NAME_ERROR_MESSAGE: &'static str = "The name of a device may not be empty!";
pub const EMPTY_DEVICE_INTERFACE_ERROR_MESSAGE: &'static str = "Enter a valid interface name!";
pub const EMPTY_DEVICE_NAME_ERROR_MESSAGE: &str = "The name of a device may not be empty!";
pub const EMPTY_DEVICE_INTERFACE_ERROR_MESSAGE: &str = "Enter a valid interface name!";

#[derive(thiserror::Error, Clone, Debug)]
pub enum PeerMisconfigurationError {
Expand Down Expand Up @@ -46,23 +46,30 @@ pub struct UserDeviceConfiguration {
}

impl TryFrom<UserPeerConfiguration> for PeerDescriptor {

type Error = PeerMisconfigurationError;

fn try_from(configuration: UserPeerConfiguration) -> Result<Self, Self::Error> {
let name = configuration.name
let name = configuration
.name
.right_ok_or(PeerMisconfigurationError::InvalidPeerName)
.and_then(|name| PeerName::try_from(name)
.map_err(|_| PeerMisconfigurationError::InvalidPeerName))?;
let location = configuration.location
.and_then(|name| {
PeerName::try_from(name).map_err(|_| PeerMisconfigurationError::InvalidPeerName)
})?;
let location = configuration
.location
.right_ok_or(PeerMisconfigurationError::InvalidPeerName)
.and_then(|location| PeerLocation::try_from(location)
.map_err(|_| PeerMisconfigurationError::InvalidPeerName))?;
let devices = configuration.devices.into_iter()
.and_then(|location| {
PeerLocation::try_from(location)
.map_err(|_| PeerMisconfigurationError::InvalidPeerName)
})?;
let devices = configuration
.devices
.into_iter()
.map(|signal| signal.get_untracked())
.map(|configuration| DeviceDescriptor::try_from(configuration)
.map_err(PeerMisconfigurationError::InvalidDevice)
)
.map(|configuration| {
DeviceDescriptor::try_from(configuration)
.map_err(PeerMisconfigurationError::InvalidDevice)
})
.collect::<Result<Vec<_>, _>>()?;
Ok(PeerDescriptor {
id: configuration.id,
Expand All @@ -77,13 +84,16 @@ impl TryFrom<UserDeviceConfiguration> for DeviceDescriptor {
type Error = DeviceMisconfigurationError;

fn try_from(configuration: UserDeviceConfiguration) -> Result<Self, Self::Error> {
let name = configuration.name
let name = configuration
.name
.right_ok_or(DeviceMisconfigurationError::InvalidDeviceName)?;
let interface = configuration.interface
let interface = configuration
.interface
.right_ok_or(DeviceMisconfigurationError::InvalidDeviceInterface)
.and_then(|interface_name| NetworkInterfaceName::try_from(interface_name)
.map_err(|_| DeviceMisconfigurationError::InvalidDeviceInterface)
)?;
.and_then(|interface_name| {
NetworkInterfaceName::try_from(interface_name)
.map_err(|_| DeviceMisconfigurationError::InvalidDeviceInterface)
})?;
Ok(DeviceDescriptor {
id: configuration.id,
name,
Expand Down

0 comments on commit b753071

Please sign in to comment.