Skip to content

Commit

Permalink
refactor: move all plugin patternfly components into core
Browse files Browse the repository at this point in the history
  • Loading branch information
HoKim98 committed Jul 18, 2024
1 parent 54fdeff commit f7f977b
Show file tree
Hide file tree
Showing 21 changed files with 258 additions and 214 deletions.
3 changes: 2 additions & 1 deletion crates/cassette-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ workspace = true
[features]
default = []
api = ["dep:actix-web"]
ui = ["dep:gloo-net", "dep:yew"]
ui = ["dep:gloo-net", "dep:patternfly-yew", "dep:yew"]

# net
stream = ["dep:anyhow", "dep:wasm-streams"]
Expand All @@ -38,6 +38,7 @@ garde = { workspace = true }
gloo-net = { workspace = true, optional = true }
k8s-openapi = { workspace = true }
kube = { workspace = true, features = ["derive"] }
patternfly-yew = { workspace = true, optional = true }
schemars = { workspace = true, features = ["derive"] }
serde = { workspace = true, features = ["derive", "rc"] }
serde_json = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/cassette-core/src/cassette.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use uuid::Uuid;
#[cfg(feature = "ui")]
use yew::prelude::*;

use crate::component::CassetteComponentSpec;
use crate::components::CassetteComponentSpec;
#[cfg(feature = "ui")]
use crate::net::fetch::{FetchState, FetchStateHandle};

Expand Down
114 changes: 0 additions & 114 deletions crates/cassette-core/src/component.rs
Original file line number Diff line number Diff line change
@@ -1,115 +1 @@
use kube::CustomResource;
use schemars::JsonSchema;
#[cfg(feature = "ui")]
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};

use crate::task::CassetteTask;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, CustomResource)]
#[kube(
group = "cassette.ulagbulag.io",
version = "v1alpha1",
kind = "CassetteComponent",
root = "CassetteComponentCrd",
shortname = "casc",
namespaced,
printcolumn = r#"{
"name": "created-at",
"type": "date",
"description": "created time",
"jsonPath": ".metadata.creationTimestamp"
}"#,
printcolumn = r#"{
"name": "version",
"type": "integer",
"description": "component version",
"jsonPath": ".metadata.generation"
}"#
)]
#[serde(rename_all = "camelCase")]
pub struct CassetteComponentSpec {
#[serde(default)]
pub tasks: Vec<CassetteTask>,
}

#[cfg(feature = "ui")]
pub trait ComponentRenderer<Spec> {
fn render(
self,
ctx: &mut crate::cassette::CassetteContext,
spec: Spec,
) -> crate::task::TaskResult<Option<Self>>
where
Self: Sized;
}

#[cfg(feature = "ui")]
pub trait ComponentRendererExt<Spec>
where
Self: Default + Serialize + DeserializeOwned + ComponentRenderer<Spec>,
Spec: DeserializeOwned,
{
fn render_with(
mut ctx: crate::cassette::CassetteContext,
spec: &crate::task::TaskSpec,
) -> crate::task::TaskResult<()>
where
Self: Sized,
{
use serde_json::Value;

fn replace_key(
ctx: &crate::cassette::CassetteContext,
spec: &crate::task::TaskSpec,
value: &Value,
) -> Result<Value, String> {
match value {
Value::Null => Ok(Value::Null),
Value::Bool(data) => Ok(Value::Bool(*data)),
Value::Number(data) => Ok(Value::Number(data.clone())),
Value::String(data) => {
if data.starts_with(":/") {
ctx.get(&data[1..]).cloned()
} else if data.starts_with("~/") {
spec.get(&data[1..]).cloned()
} else if data.starts_with("\\:/") || data.starts_with("\\~/") {
Ok(Value::String(data[1..].into()))
} else {
Ok(Value::String(data.clone()))
}
}
Value::Array(array) => array
.iter()
.map(|value| replace_key(ctx, spec, value))
.collect::<Result<_, _>>()
.map(Value::Array),
Value::Object(map) => map
.iter()
.map(|(key, value)| {
replace_key(ctx, spec, value).map(|value| (key.clone(), value))
})
.collect::<Result<_, _>>()
.map(Value::Object),
}
}

let state = ctx.get_task_state()?.unwrap_or_default();

let spec = replace_key(&ctx, spec, &spec.0)?;
let spec = ::serde_json::from_value(spec)
.map_err(|error| format!("Failed to parse task spec: {error}"))?;

let state = <Self as ComponentRenderer<Spec>>::render(state, &mut ctx, spec)
.and_then(crate::task::TaskState::try_into_spec)?;
Ok(ctx.set(state))
}
}

#[cfg(feature = "ui")]
impl<Spec, T> ComponentRendererExt<Spec> for T
where
Self: Default + Serialize + DeserializeOwned + ComponentRenderer<Spec>,
Spec: DeserializeOwned,
{
}
18 changes: 18 additions & 0 deletions crates/cassette-core/src/components/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use patternfly_yew::prelude::*;
use yew::prelude::*;

#[derive(Clone, Debug, PartialEq, Properties)]
pub struct Props {
pub msg: AttrValue,
}

#[function_component(Error)]
pub fn error(props: &Props) -> Html {
let Props { msg } = props;

html! {
<Content>
<p>{ msg }</p>
</Content>
}
}
18 changes: 18 additions & 0 deletions crates/cassette-core/src/components/loading.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use patternfly_yew::prelude::*;
use yew::prelude::*;

#[function_component(Loading)]
pub fn loading() -> Html {
html! {
<Flex >
<FlexItem>
<Spinner size={ SpinnerSize::Lg } />
</FlexItem>
<FlexItem modifiers={[ FlexModifier::Align(Alignment::Center) ]}>
<Content>
<p>{ "Loading..." }</p>
</Content>
</FlexItem>
</Flex>
}
}
120 changes: 120 additions & 0 deletions crates/cassette-core/src/components/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#[cfg(feature = "ui")]
pub mod error;
#[cfg(feature = "ui")]
pub mod loading;

use kube::CustomResource;
use schemars::JsonSchema;
#[cfg(feature = "ui")]
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};

use crate::task::CassetteTask;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, CustomResource)]
#[kube(
group = "cassette.ulagbulag.io",
version = "v1alpha1",
kind = "CassetteComponent",
root = "CassetteComponentCrd",
shortname = "casc",
namespaced,
printcolumn = r#"{
"name": "created-at",
"type": "date",
"description": "created time",
"jsonPath": ".metadata.creationTimestamp"
}"#,
printcolumn = r#"{
"name": "version",
"type": "integer",
"description": "component version",
"jsonPath": ".metadata.generation"
}"#
)]
#[serde(rename_all = "camelCase")]
pub struct CassetteComponentSpec {
#[serde(default)]
pub tasks: Vec<CassetteTask>,
}

#[cfg(feature = "ui")]
pub trait ComponentRenderer<Spec> {
fn render(
self,
ctx: &mut crate::cassette::CassetteContext,
spec: Spec,
) -> crate::task::TaskResult<Option<Self>>
where
Self: Sized;
}

#[cfg(feature = "ui")]
pub trait ComponentRendererExt<Spec>
where
Self: Default + Serialize + DeserializeOwned + ComponentRenderer<Spec>,
Spec: DeserializeOwned,
{
fn render_with(
mut ctx: crate::cassette::CassetteContext,
spec: &crate::task::TaskSpec,
) -> crate::task::TaskResult<()>
where
Self: Sized,
{
use serde_json::Value;

fn replace_key(
ctx: &crate::cassette::CassetteContext,
spec: &crate::task::TaskSpec,
value: &Value,
) -> Result<Value, String> {
match value {
Value::Null => Ok(Value::Null),
Value::Bool(data) => Ok(Value::Bool(*data)),
Value::Number(data) => Ok(Value::Number(data.clone())),
Value::String(data) => {
if data.starts_with(":/") {
ctx.get(&data[1..]).cloned()
} else if data.starts_with("~/") {
spec.get(&data[1..]).cloned()
} else if data.starts_with("\\:/") || data.starts_with("\\~/") {
Ok(Value::String(data[1..].into()))
} else {
Ok(Value::String(data.clone()))
}
}
Value::Array(array) => array
.iter()
.map(|value| replace_key(ctx, spec, value))
.collect::<Result<_, _>>()
.map(Value::Array),
Value::Object(map) => map
.iter()
.map(|(key, value)| {
replace_key(ctx, spec, value).map(|value| (key.clone(), value))
})
.collect::<Result<_, _>>()
.map(Value::Object),
}
}

let state = ctx.get_task_state()?.unwrap_or_default();

let spec = replace_key(&ctx, spec, &spec.0)?;
let spec = ::serde_json::from_value(spec)
.map_err(|error| format!("Failed to parse task spec: {error}"))?;

let state = <Self as ComponentRenderer<Spec>>::render(state, &mut ctx, spec)
.and_then(crate::task::TaskState::try_into_spec)?;
Ok(ctx.set(state))
}
}

#[cfg(feature = "ui")]
impl<Spec, T> ComponentRendererExt<Spec> for T
where
Self: Default + Serialize + DeserializeOwned + ComponentRenderer<Spec>,
Spec: DeserializeOwned,
{
}
2 changes: 1 addition & 1 deletion crates/cassette-core/src/document.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize, Serializer};

use crate::{cassette::CassetteCrd, component::CassetteComponentCrd};
use crate::{cassette::CassetteCrd, components::CassetteComponentCrd};

#[derive(Clone, Debug, Deserialize)]
#[serde(tag = "kind")]
Expand Down
7 changes: 6 additions & 1 deletion crates/cassette-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
pub mod cassette;
pub mod component;
pub mod components;
pub mod document;
pub mod net;
pub mod result;
pub mod task;

#[cfg(feature = "ui")]
pub mod prelude {
pub use crate::components::{error::Error, loading::Loading};
}
2 changes: 1 addition & 1 deletion crates/cassette-gateway/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::Arc;

use cassette_core::{
cassette::{Cassette, CassetteCrd, CassetteRef},
component::CassetteComponentCrd,
components::CassetteComponentCrd,
};
use cassette_loader_core::CassetteDB as CassetteDBInner;
use tokio::sync::RwLock;
Expand Down
2 changes: 1 addition & 1 deletion crates/cassette-gateway/src/reloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;

use anyhow::Result;
use ark_core::signal::FunctionSignal;
use cassette_core::{cassette::CassetteCrd, component::CassetteComponentCrd};
use cassette_core::{cassette::CassetteCrd, components::CassetteComponentCrd};
use futures::{TryFuture, TryStreamExt};
use kube::{
runtime::watcher::{watcher, Config, Error as WatcherError, Event},
Expand Down
2 changes: 1 addition & 1 deletion crates/cassette-loader-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};

use cassette_core::{
cassette::{Cassette, CassetteCrd, CassetteRef},
component::CassetteComponentCrd,
components::CassetteComponentCrd,
net::DEFAULT_NAMESPACE,
};
use kube::ResourceExt;
Expand Down
2 changes: 1 addition & 1 deletion crates/cassette-operator/src/ctx/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{sync::Arc, time::Duration};
use anyhow::Result;
use ark_core_k8s::manager::Manager;
use async_trait::async_trait;
use cassette_core::component::CassetteComponentCrd;
use cassette_core::components::CassetteComponentCrd;
use kube::{runtime::controller::Action, Error, ResourceExt};
use tracing::{instrument, Level};

Expand Down
Loading

0 comments on commit f7f977b

Please sign in to comment.