use bigml::resource::{Dataset, Id, Source};
use std::{fmt, str::FromStr};
use crate::common::*;
mod data_type;
mod local_data;
mod schema;
mod source;
mod write_local_data;
use local_data::local_data_helper;
use schema::schema_helper;
use write_local_data::write_local_data_helper;
#[derive(Clone, Debug)]
enum BigMlAction {
CreateDataset,
CreateDatasets,
CreateSource,
CreateSources,
ReadDataset(Id<Dataset>),
OutputSource(Id<Source>),
}
pub(self) struct CreateOptions {
pub(self) concat_csv_streams: bool,
pub(self) convert_to_dataset: bool,
}
#[derive(Clone, Debug)]
pub(crate) struct BigMlLocator {
action: BigMlAction,
}
impl BigMlLocator {
pub fn create_dataset() -> Self {
Self {
action: BigMlAction::CreateDataset,
}
}
pub fn create_datasets() -> Self {
Self {
action: BigMlAction::CreateDatasets,
}
}
pub fn create_source() -> Self {
Self {
action: BigMlAction::CreateSource,
}
}
pub fn create_sources() -> Self {
Self {
action: BigMlAction::CreateSources,
}
}
pub fn read_dataset(id: Id<Dataset>) -> Self {
Self {
action: BigMlAction::ReadDataset(id),
}
}
pub(self) fn output_source(id: Id<Source>) -> Self {
Self {
action: BigMlAction::OutputSource(id),
}
}
pub(self) fn to_create_options(&self) -> Option<CreateOptions> {
match &self.action {
BigMlAction::CreateDataset => Some(CreateOptions {
concat_csv_streams: true,
convert_to_dataset: true,
}),
BigMlAction::CreateDatasets => Some(CreateOptions {
concat_csv_streams: false,
convert_to_dataset: true,
}),
BigMlAction::CreateSource => Some(CreateOptions {
concat_csv_streams: true,
convert_to_dataset: false,
}),
BigMlAction::CreateSources => Some(CreateOptions {
concat_csv_streams: false,
convert_to_dataset: false,
}),
BigMlAction::ReadDataset(_) | BigMlAction::OutputSource(_) => None,
}
}
}
impl fmt::Display for BigMlLocator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.action {
BigMlAction::CreateDataset => write!(f, "bigml:dataset"),
BigMlAction::CreateDatasets => write!(f, "bigml:datasets"),
BigMlAction::CreateSource => write!(f, "bigml:source"),
BigMlAction::CreateSources => write!(f, "bigml:sources"),
BigMlAction::ReadDataset(id) => write!(f, "bigml:{}", id),
BigMlAction::OutputSource(id) => write!(f, "bigml:{}", id),
}
}
}
impl FromStr for BigMlLocator {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
if s == "bigml:dataset" {
Ok(BigMlLocator::create_dataset())
} else if s == "bigml:datasets" {
Ok(BigMlLocator::create_datasets())
} else if s == "bigml:source" {
Ok(BigMlLocator::create_source())
} else if s == "bigml:sources" {
Ok(BigMlLocator::create_sources())
} else if s.starts_with(Self::scheme()) {
let id = s[Self::scheme().len()..].parse::<Id<Dataset>>()?;
Ok(BigMlLocator::read_dataset(id))
} else {
Err(format_err!("expected {} to begin with bigml:", s))
}
}
}
impl Locator for BigMlLocator {
fn as_any(&self) -> &dyn Any {
self
}
fn schema(&self, _ctx: Context) -> BoxFuture<Option<Schema>> {
schema_helper(self.to_owned()).boxed()
}
fn local_data(
&self,
_ctx: Context,
shared_args: SharedArguments<Unverified>,
source_args: SourceArguments<Unverified>,
) -> BoxFuture<Option<BoxStream<CsvStream>>> {
local_data_helper(self.clone(), shared_args, source_args).boxed()
}
fn display_output_locators(&self) -> DisplayOutputLocators {
match &self.action {
BigMlAction::CreateDataset
| BigMlAction::CreateDatasets
| BigMlAction::CreateSource
| BigMlAction::CreateSources => DisplayOutputLocators::ByDefault,
_ => DisplayOutputLocators::IfRequested,
}
}
fn write_local_data(
&self,
ctx: Context,
data: BoxStream<CsvStream>,
shared_args: SharedArguments<Unverified>,
dest_args: DestinationArguments<Unverified>,
) -> BoxFuture<BoxStream<BoxFuture<BoxLocator>>> {
write_local_data_helper(ctx, self.clone(), data, shared_args, dest_args)
.boxed()
}
}
impl LocatorStatic for BigMlLocator {
fn scheme() -> &'static str {
"bigml:"
}
fn features() -> Features {
Features {
locator: LocatorFeatures::Schema
| LocatorFeatures::LocalData
| LocatorFeatures::WriteLocalData,
write_schema_if_exists: EnumSet::empty(),
source_args: EnumSet::empty(),
dest_args: DestinationArgumentsFeatures::DriverArgs.into(),
dest_if_exists: EnumSet::all(),
_placeholder: (),
}
}
}