use serde::{Deserialize, Serialize};
use serde_json;
use std::{fmt, str::FromStr};
use super::id::*;
use super::library::Library;
use super::status::*;
use super::{Resource, ResourceCommon};
use crate::errors::*;
#[derive(Clone, Debug, Deserialize, Resource, Serialize)]
#[api_name = "script"]
pub struct Script {
#[serde(flatten)]
pub common: ResourceCommon,
pub resource: Id<Script>,
pub status: GenericStatus,
pub source_code: String,
#[serde(skip)]
_placeholder: (),
}
#[derive(Debug, Serialize)]
pub struct Args {
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub imports: Vec<Id<Library>>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub inputs: Vec<Input>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub outputs: Vec<Output>,
pub source_code: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub tags: Vec<String>,
#[serde(skip)]
_placeholder: (),
}
impl Args {
pub fn new<S: Into<String>>(source_code: S) -> Args {
Args {
category: Default::default(),
description: Default::default(),
imports: Default::default(),
inputs: Default::default(),
name: Default::default(),
outputs: Default::default(),
source_code: source_code.into(),
tags: Default::default(),
_placeholder: (),
}
}
}
impl super::Args for Args {
type Resource = Script;
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Input {
pub name: String,
#[serde(rename = "type")]
pub type_: Type,
pub default: Option<serde_json::Value>,
pub description: Option<String>,
#[serde(default, skip_serializing)]
_placeholder: (),
}
impl Input {
pub fn new<S: Into<String>>(name: S, type_: Type) -> Input {
Input {
name: name.into(),
type_,
default: None,
description: None,
_placeholder: (),
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Output {
pub name: String,
#[serde(rename = "type")]
pub type_: Type,
pub description: Option<String>,
#[serde(default, skip_serializing)]
_placeholder: (),
}
impl Output {
pub fn new<S: Into<String>>(name: S, type_: Type) -> Output {
Output {
name: name.into(),
type_,
description: None,
_placeholder: (),
}
}
}
macro_rules! declare_type_enum {
($($name:ident => $api_name:expr,)+) => (
#[derive(Clone, Copy, Debug, Deserialize, Eq, Serialize, PartialEq)]
#[allow(missing_docs)]
pub enum Type {
$(
#[serde(rename = $api_name)]
$name,
)+
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
$( Type::$name => $api_name.fmt(f), )*
}
}
}
impl FromStr for Type {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
match s {
$( $api_name => Ok(Type::$name), )*
_ => {
Err(format_err!("Unknown BigML type: {:?}", s).into())
}
}
}
}
)
}
declare_type_enum! {
String => "string",
Categorical => "categorical",
Text => "text",
Items => "items",
Number => "number",
Numeric => "numeric",
Integer => "integer",
Boolean => "boolean",
List => "list",
Map => "map",
ListOfString => "list-of-string",
ListOfInteger => "list-of-integer",
ListOfNumber => "list-of-number",
ListOfMap => "list-of-map",
ListOfBoolean => "list-of-boolean",
ResourceId => "resource-id",
SupervisedModelId => "supervised-model-id",
ProjectId => "project-id",
SourceId => "source-id",
DatasetId => "dataset-id",
SampleId => "sample-id",
ModelId => "model-id",
EnsembleId => "ensemble-id",
LogisticRegressionId => "logisticregression-id",
DeepnetId => "deepnet-id",
TimeseriesId => "timeseries-id",
PredictionId => "prediction-id",
BatchPredictionId => "batchprediction-id",
EvaluationId => "evaluation-id",
AnomalyId => "anomaly-id",
AnomalyScoreId => "anomalyscore-id",
BatchAnomolayScoreId => "batchanomalyscore-id",
ClusterId => "cluster-id",
CentroidId => "centroid-id",
BatchCentroidId => "batchcentroid-id",
AssociationId => "association-id",
AssociationSetId => "associationset-id",
TopicModelId => "topicmodel-id",
TopicDistributionId => "topicdistribution-id",
BatchTopicDistribution => "batchtopicdistribution-id",
CorrelationId => "correlation-id",
StatisticalTestId => "statisticaltest-id",
LibraryId => "library-id",
ScriptId => "script-id",
ExecutionId => "execution-id",
Configuration => "configuration-id",
}
#[test]
fn parse_type() {
let ty: Type = "categorical".parse().unwrap();
assert_eq!(ty, Type::Categorical);
}
#[test]
fn display_type() {
assert_eq!(format!("{}", Type::Categorical), "categorical");
}