Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add schema and models for train schedule V2 #6532

Merged
merged 9 commits into from
Feb 27, 2024
663 changes: 365 additions & 298 deletions editoast/Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions editoast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ cfg-if = "1.0.0"
validator = { version = "0.16.1", features = ["derive"] }
inventory = "0.3"
heck = "0.4.1"
iso8601 = "0.6.1"

[dev-dependencies]
async-std = { version = "1.12.0", features = ["attributes", "tokio1"] }
Expand Down
1 change: 1 addition & 0 deletions editoast/editoast_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ pub fn search_config_store(input: proc_macro::TokenStream) -> proc_macro::TokenS
/// * `#[model(primary)]`: implies `identifier` ; marks the field as the primary key of the table
/// * `#[model(json)]`: wraps the row field with `diesel_jsonb::JsonValue` (diesel column type: `diesel_jsonb::Json<T>`)
/// * `#[model(to_string)]`: calls `to_string()` before writing the field to the database and calls `String::from` after reading (diesel column type: String)
/// * `#[model(to_enum)]`: is converted as `u8` before writing the field to the database and calls `FromRepr::from_repr` after reading (diesel column type: TinyInt)
/// * `#[model(remote = "T")]`: calls `Into::<T>::into` before writing the field to the database and calls `T::from` after reading (diesel column type: T)
/// * `#[model(geo)]` **TODO**: TBD
///
Expand Down
42 changes: 32 additions & 10 deletions editoast/editoast_derive/src/modelv2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ struct ModelFieldOption {
#[darling(default)]
to_string: bool,
#[darling(default)]
to_enum: bool,
#[darling(default)]
remote: Option<syn::Type>,
}

Expand Down Expand Up @@ -182,6 +184,7 @@ enum FieldTransformation {
Json,
Geo,
ToString,
ToEnum(syn::Type),
}

impl FieldTransformation {
Expand All @@ -190,15 +193,17 @@ impl FieldTransformation {
json: bool,
geo: bool,
to_string: bool,
to_enum: Option<syn::Type>,
) -> Result<Option<Self>> {
match (remote, json, geo, to_string) {
(Some(ty), false, false, false) => Ok(Some(Self::Remote(ty))),
(None, true, false, false) => Ok(Some(Self::Json)),
(None, false, true, false) => Ok(Some(Self::Geo)),
(None, false, false, true) => Ok(Some(Self::ToString)),
(None, false, false, false) => Ok(None),
match (remote, json, geo, to_string, to_enum) {
(Some(ty), false, false, false, None) => Ok(Some(Self::Remote(ty))),
(None, true, false, false, None) => Ok(Some(Self::Json)),
(None, false, true, false, None) => Ok(Some(Self::Geo)),
(None, false, false, true, None) => Ok(Some(Self::ToString)),
(None, false, false, false, Some(ty)) => Ok(Some(Self::ToEnum(ty))),
(None, false, false, false, None) => Ok(None),
_ => Err(Error::custom(
"Model: remote, json, geo, and to_string attributes are mutually exclusive",
"Model: remote, json, geo, to_string and to_enum attributes are mutually exclusive",
)),
}
}
Expand All @@ -211,9 +216,19 @@ impl ModelField {
.ok_or(Error::custom("Model: only works for named structs"))?;
let column = value.column.unwrap_or_else(|| ident.to_string());
let builder_ident = value.builder_fn.unwrap_or_else(|| ident.clone());
let transform =
FieldTransformation::from_args(value.remote, value.json, value.geo, value.to_string)
.map_err(|e| e.with_span(&ident))?;
let to_enum = match value.to_enum {
true => Some(value.ty.clone()),
false => None,
};

let transform = FieldTransformation::from_args(
value.remote,
value.json,
value.geo,
value.to_string,
to_enum,
)
.map_err(|e| e.with_span(&ident))?;
Ok(Self {
ident,
builder_ident,
Expand All @@ -234,6 +249,9 @@ impl ModelField {
Some(FieldTransformation::Json) => quote! { diesel_json::Json(#expr) },
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
Some(FieldTransformation::ToString) => quote! { #expr.to_string() },
Some(FieldTransformation::ToEnum(_)) => {
quote! { #expr as i16 }
}
None => quote! { #expr },
}
}
Expand All @@ -245,6 +263,9 @@ impl ModelField {
Some(FieldTransformation::Json) => quote! { #expr.0 },
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
Some(FieldTransformation::ToString) => quote! { String::from(#expr.parse()) },
Some(FieldTransformation::ToEnum(ref ty)) => {
quote! { #ty::from_repr(#expr as usize).expect("Invalid variant repr") }
}
None => quote! { #expr },
}
}
Expand All @@ -256,6 +277,7 @@ impl ModelField {
Some(FieldTransformation::Json) => quote! { diesel_json::Json<#ty> },
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
Some(FieldTransformation::ToString) => quote! { String },
Some(FieldTransformation::ToEnum(_)) => quote! { i16 },
None => quote! { #ty },
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TABLE train_schedule_v2;
DROP TABLE timetable_v2;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CREATE TABLE timetable_v2 (
id int8 PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
electrical_profile_set_id int8 NULL REFERENCES electrical_profile_set(id) ON DELETE CASCADE
);
CREATE TABLE train_schedule_v2 (
id int8 PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
train_name varchar(128) NOT NULL,
labels text [] NOT NULL,
rolling_stock_name varchar(128) NOT NULL,
timetable_id int8 NOT NULL REFERENCES timetable_v2(id) ON DELETE CASCADE,
start_time timestamptz NOT NULL,
schedule jsonb NOT NULL,
margins jsonb NOT NULL,
initial_speed float8 NOT NULL,
comfort smallint NOT NULL,
path jsonb NOT NULL,
constraint_distribution smallint NOT NULL,
speed_limit_tag varchar(128),
power_restrictions jsonb NOT NULL,
options jsonb NOT NULL
);
Loading
Loading