1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
//! Resource types manipulated by the BigML API. use serde::{Deserialize, Serialize}; use std::fmt; // We re-export everything from our support submodules. pub use self::id::*; pub use self::status::*; // We only re-export the main names from our resource submodules. For any // other types, use a fully-qualified name. pub use self::batchprediction::BatchPrediction; pub use self::ensemble::Ensemble; pub use self::evaluation::Evaluation; pub use self::execution::Execution; pub use self::script::Script; pub use self::source::Source; /// A shared interface to all BigML resource types. pub trait Resource: fmt::Debug + Deserialize { /// The prefix used for all IDs of this type. fn id_prefix() -> &'static str; /// The URL path used to create a new resource of this type. fn create_path() -> &'static str; /// The ID of this resource. fn id(&self) -> &Id<Self>; /// The status code for this resource. /// /// TODO: Does this need to go in a separate trait in order to maintain /// trait object support? fn status(&self) -> &Status; } /// Arguments which can be used to create a resource. pub trait Args: fmt::Debug + Serialize { /// The resource type these arguments create. type Resource: Resource; } macro_rules! resource { ( api_name $string_name:expr; // The pattern `$(<$($Ty : $Tr),*>)*` is overly generous. We want // to match an optional set of type parameters of the form `<Name: // Trait, ...>`, but Rust macros have no easy "match 0 or 1" // mechanism, so we match 0 or more `<...>` patterns instead. $(#[ $meta:meta ])* pub struct $name:ident $(<$($Ty:ident : $Tr:ident),*>)* { $( $(#[ $field_type_meta:meta ])* pub $field_name:ident: $field_ty:ty, )* } ) => { $(#[ $meta ])* pub struct $name $(<$($Ty : $Tr),*>)* { // Start by declaring the fields which appear on every resource // type. We should theoretically implement this using // inheritance, but Rust doesn't have implementation // inheritance. We could also implement this using various // other Rust patterns like delegation, but that would mean // that serde could no longer assume a simple 1-to-1 mapping // between Rust and JSON types. So we just use a macro to do // some code gen, and we define a `Resource` trait that we can // use to access any duplicated bits using a single API. /// Used to classify by industry or category. 0 is "Miscellaneous". pub category: i64, /// An HTTP status code, typically either 201 or 200. /// /// TODO: Deserialize as a `reqwest::StatusCode`? pub code: u16, // The time this resource was created. // // TODO: The response is missing the `Z`, which makes chrono sad. //pub created: DateTime<UTC>, /// Was this created in development mode? pub dev: Option<bool>, /// Text describing this resource. May contain limited Markdown. pub description: String, /// The name of this resource pub name: String, // What project is this associated with? // // TODO: Define `Project` type and then enable this. //pub project: Id<Project>, /// Has this been shared using a private link? pub shared: bool, /// Was this created using a subscription plan? pub subscription: bool, /// User-defined tags. pub tags: Vec<String>, // The last time this was updated. // // TODO: The response is missing the `Z`, which makes chrono sad. //pub updated: DateTime<UTC>, /// The ID of this execution. pub resource: Id<$name $(<$($Ty),*>)*>, /// Having one hidden field makes it possible to extend this struct /// without breaking semver API guarantees. #[serde(default, skip_serializing)] _hidden: (), $( $(#[ $field_type_meta ])* pub $field_name: $field_ty ),* } impl $(<$($Ty : $Tr),*>)* Resource for $name $(<$($Ty),*>)* { fn id_prefix() -> &'static str { concat!($string_name, "/") } fn create_path() -> &'static str { concat!("/", $string_name) } fn id(&self) -> &Id<Self> { &self.resource } fn status(&self) -> &Status { &self.status } } }; } // Support modules defining general types. mod id; mod status; // Individual resource types. These need to go after our `response!` macro // definition, above, because macros are processed as source is being read. pub mod batchprediction; pub mod ensemble; pub mod evaluation; pub mod execution; pub mod script; pub mod source;