Skip to content

Commit

Permalink
feat(all): impl 2/n
Browse files Browse the repository at this point in the history
  • Loading branch information
martsokha committed Dec 12, 2024
1 parent bd11c99 commit 7c532bb
Show file tree
Hide file tree
Showing 19 changed files with 391 additions and 456 deletions.
File renamed without changes.
5 changes: 4 additions & 1 deletion crates/task/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ futures = { workspace = true }
pin-project-lite = { workspace = true }
thiserror = { workspace = true }

derive_more = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
jsonschema = { workspace = true }

derive_more = { workspace = true }
tracing = { workspace = true }
ecow = { workspace = true }
tower = { workspace = true }
Expand Down
51 changes: 9 additions & 42 deletions crates/task/context/failure.rs
Original file line number Diff line number Diff line change
@@ -1,60 +1,27 @@
use std::error::Error;

use serde::{Deserialize, Serialize};
use thiserror::Error;

// TODO: wrap box error instead

/// Unrecoverable failure duration [`TaskHandler`] execution.
///
/// [`TaskHandler`]: crate::handler::TaskHandler
#[derive(Debug, Error, Serialize, Deserialize)]
#[derive(Debug, thiserror::Error)]
#[error("internal handler error")]
#[must_use = "errors do nothing unless you use them"]
#[error("failure during `TaskHandler` execution")]
pub struct TaskError {
name: String,
message: String,
inner: Box<dyn Error>,
}

impl TaskError {
/// Returns a new [`TaskError`].
pub fn new() -> Self {
#[inline]
pub fn new<E>(inner: E) -> Self
where
E: Error + 'static,
{
Self {
name: "".to_owned(),
message: "".to_owned(),
inner: Box::new(inner),
}
}

/// Returns the underlying error's name.
#[inline]
pub fn name(&self) -> &str {
&self.name
}

/// Returns the underlying error's message.
#[inline]
pub fn message(&self) -> &str {
&self.message
}
}

impl From<Box<dyn Error>> for TaskError {
fn from(value: Box<dyn Error>) -> Self {
todo!()
}
}

/// Specialized [`Result`] alias for the [`TaskError`] type.
pub type TaskResult<T, E = TaskError> = Result<T, E>;

#[cfg(test)]
mod test {
use crate::context::TaskError;
use crate::Result;

#[test]
fn instance() -> Result<()> {
let _ = TaskError::new();
Ok(())
}
}
10 changes: 0 additions & 10 deletions crates/task/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ pub mod builders {
pub use super::response::TaskResponseBuilder;
}

pub mod storages {
//! [`TaskRequest`] and [`TaskResponse`] storages.
//!
//! [`TaskRequest`]: crate::context::TaskRequest
//! [`TaskResponse`]: crate::context::TaskResponse
pub use super::request::{Fields, Secrets};
pub use super::response::Metrics;
}

pub use crate::context::failure::{TaskError, TaskResult};
pub use crate::context::request::TaskRequest;
pub use crate::context::response::TaskResponse;
Expand Down
78 changes: 27 additions & 51 deletions crates/task/context/request.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,18 @@
use std::collections::HashMap;
use std::fmt;

use derive_more::{Deref, DerefMut, From};
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::routing::Layers;
use crate::routing::layers::Layers;

/// TODO.
#[derive(Debug, Default, Clone, Serialize, Deserialize, From)]
#[must_use = "requests do nothing unless you serialize them"]
pub struct Fields {
inner: HashMap<String, String>,
}

impl Fields {
/// Returns an empty [`Fields`] store.
#[inline]
pub fn new() -> Self {
Self::default()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Deref, From)]
pub struct Inputs(pub Value);

/// TODO.
#[derive(Debug, Default, Clone, Serialize, Deserialize, From)]
#[must_use = "requests do nothing unless you serialize them"]
pub struct Secrets {
inner: HashMap<String, String>,
}

impl Secrets {
/// Returns an empty [`Secrets`] store.
#[inline]
pub fn new() -> Self {
Self::default()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Deref, From)]
pub struct Secrets(pub Value);

/// Serializable [`TaskHandler`] service request.
///
Expand All @@ -46,9 +24,9 @@ pub struct TaskRequest<T = ()> {
#[deref_mut]
inner: T,

fields: Fields,
secrets: Secrets,
layers: Layers,
pub(crate) inputs: Inputs,
pub(crate) secrets: Secrets,
pub(crate) layers: Layers,
}

impl<T> TaskRequest<T> {
Expand All @@ -57,8 +35,8 @@ impl<T> TaskRequest<T> {
pub fn new(inner: T) -> Self {
Self {
inner,
fields: Fields::new(),
secrets: Secrets::new(),
inputs: Inputs(Value::default()),
secrets: Secrets(Value::default()),
layers: Layers::new(),
}
}
Expand All @@ -79,7 +57,7 @@ impl<T> TaskRequest<T> {
impl<T> fmt::Debug for TaskRequest<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TaskRequest")
.field("fields", &self.fields)
.field("inputs", &self.inputs)
.field("secrets", &self.secrets)
.finish_non_exhaustive()
}
Expand All @@ -92,8 +70,8 @@ impl<T> fmt::Debug for TaskRequest<T> {
#[must_use = "requests do nothing unless you serialize them"]
pub struct TaskRequestBuilder<T> {
inner: T,
fields: Option<Fields>,
secrets: Option<Secrets>,
inputs: Option<Value>,
secrets: Option<Value>,
layers: Option<Layers>,
}

Expand All @@ -103,26 +81,23 @@ impl<T> TaskRequestBuilder<T> {
pub fn new(inner: T) -> Self {
Self {
inner,
fields: None,
inputs: None,
secrets: None,
layers: None,
}
}

// TODO: Method to add a single field.
// TODO: Method to add a single secret.

/// Overrides the default value of [`TaskRequest`]`::fields`.
/// Overrides the default value of [`TaskRequest`]`::inputs`.
#[inline]
pub fn with_fields(mut self, fields: Fields) -> Self {
self.fields = Some(fields);
pub fn with_inputs(mut self, json: Value) -> Self {
self.inputs = Some(json);
self
}

/// Overrides the default value of [`TaskRequest`]`::secrets`.
#[inline]
pub fn with_secrets(mut self, secrets: Secrets) -> Self {
self.secrets = Some(secrets);
pub fn with_secrets(mut self, json: Value) -> Self {
self.secrets = Some(json);
self
}

Expand All @@ -137,25 +112,26 @@ impl<T> TaskRequestBuilder<T> {
pub fn build(self) -> TaskRequest<T> {
TaskRequest {
inner: self.inner,
fields: self.fields.unwrap_or_default(),
secrets: self.secrets.unwrap_or_default(),
inputs: Inputs(self.inputs.unwrap_or_default()),
secrets: Secrets(self.secrets.unwrap_or_default()),
layers: self.layers.unwrap_or_default(),
}
}
}

#[cfg(test)]
mod test {
use crate::context::storages::{Fields, Secrets};
use serde_json::Value;

use crate::context::TaskRequest;
use crate::routing::Layers;
use crate::Result;

#[test]
fn build() -> Result<()> {
fn build_empty_request() -> Result<()> {
let _request = TaskRequest::builder(5)
.with_fields(Fields::new())
.with_secrets(Secrets::new())
.with_inputs(Value::default())
.with_secrets(Value::default())
.with_layers(Layers::new())
.build();
Ok(())
Expand Down
56 changes: 37 additions & 19 deletions crates/task/context/response.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
use std::collections::HashMap;
use std::fmt;

use derive_more::{Deref, DerefMut, From};
use serde::{Deserialize, Serialize};
use serde_json::Value;

/// TODO.
#[derive(Debug, Default, Clone, Serialize, Deserialize, From)]
#[must_use = "responses do nothing unless you serialize them"]
pub struct Metrics {
inner: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Deref, From)]
pub struct Outputs(pub Value);

impl Metrics {
/// Returns an empty [`Metrics`] store.
#[inline]
pub fn new() -> Self {
Self::default()
}
}
/// TODO.
#[derive(Debug, Clone, Serialize, Deserialize, Deref, From)]
pub struct Metrics(pub Value);

/// Deserializable [`TaskHandler`] service response.
///
Expand All @@ -29,7 +22,8 @@ pub struct TaskResponse<T> {
#[deref_mut]
inner: T,

metrics: Metrics,
pub(crate) outputs: Outputs,
pub(crate) metrics: Metrics,
}

impl<T> TaskResponse<T> {
Expand All @@ -38,7 +32,8 @@ impl<T> TaskResponse<T> {
pub fn new(inner: T) -> Self {
Self {
inner,
metrics: Metrics::default(),
outputs: Outputs(Value::default()),
metrics: Metrics(Value::default()),
}
}

Expand All @@ -58,6 +53,7 @@ impl<T> TaskResponse<T> {
impl<T> fmt::Debug for TaskResponse<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TaskResponse")
.field("outputs", &self.outputs)
.field("metrics", &self.metrics)
.finish_non_exhaustive()
}
Expand All @@ -70,7 +66,8 @@ impl<T> fmt::Debug for TaskResponse<T> {
#[must_use = "responses do nothing unless you serialize them"]
pub struct TaskResponseBuilder<T> {
inner: T,
metrics: Option<Metrics>,
outputs: Option<Value>,
metrics: Option<Value>,
}

impl<T> TaskResponseBuilder<T> {
Expand All @@ -79,27 +76,48 @@ impl<T> TaskResponseBuilder<T> {
pub fn new(inner: T) -> Self {
Self {
inner,
outputs: None,
metrics: None,
}
}

/// Overrides the default value of [`TaskResponse`]`::outputs`.
#[inline]
pub fn with_outputs(mut self, json: Value) -> Self {
self.outputs = Some(json);
self
}

/// Overrides the default value of [`TaskResponse`]`::metrics`.
#[inline]
pub fn with_metrics(mut self, json: Value) -> Self {
self.metrics = Some(json);
self
}

/// Returns a new [`TaskResponse`].
pub fn build(self) -> TaskResponse<T> {
TaskResponse {
inner: self.inner,
metrics: self.metrics.unwrap_or_default(),
outputs: Outputs(self.outputs.unwrap_or_default()),
metrics: Metrics(self.metrics.unwrap_or_default()),
}
}
}

#[cfg(test)]
mod test {
use serde_json::Value;

use crate::context::TaskResponse;
use crate::Result;

#[test]
fn build() -> Result<()> {
let _response = TaskResponse::builder(5).build();
fn build_empty_response() -> Result<()> {
let _response = TaskResponse::builder(5)
.with_outputs(Value::default())
.with_metrics(Value::default())
.build();
Ok(())
}
}
2 changes: 1 addition & 1 deletion crates/task/handler/metric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ mod test {

#[test]
fn from_default() -> Result<()> {
let _ = TaskMetrics::new();
let _metrics = TaskMetrics::new();
Ok(())
}
}
Loading

0 comments on commit 7c532bb

Please sign in to comment.