pub struct CmsPageUpdate {
pub content: Vec<GutenbergBlock>,
pub exercises: Vec<CmsPageExercise>,
pub exercise_slides: Vec<CmsPageExerciseSlide>,
pub exercise_tasks: Vec<CmsPageExerciseTask>,
pub url_path: String,
pub title: String,
pub chapter_id: Option<Uuid>,
pub hidden: bool,
}Fields§
§content: Vec<GutenbergBlock>§exercises: Vec<CmsPageExercise>§exercise_slides: Vec<CmsPageExerciseSlide>§exercise_tasks: Vec<CmsPageExerciseTask>§url_path: String§title: String§chapter_id: Option<Uuid>Implementations§
Source§impl CmsPageUpdate
impl CmsPageUpdate
Sourcepub fn validate_exercise_data(&self) -> ModelResult<()>
pub fn validate_exercise_data(&self) -> ModelResult<()>
Checks that each exercise has at least one slide and each slide has at least one task.
Sourcepub fn regenerate_duplicate_exercise_ids(&mut self) -> HashMap<Uuid, Uuid>
pub fn regenerate_duplicate_exercise_ids(&mut self) -> HashMap<Uuid, Uuid>
Detects exercises that share the same id within this single page and gives the duplicate occurrences fresh ids so they become independent exercises (#148).
Duplicating an exercise block in the CMS (Gutenberg) keeps the original block’s id (and the
ids of its nested slides/tasks), so a saved page can contain several exercises that reference
the same backend exercise. Without this, the upsert collapses them into a single row through
ON CONFLICT (id) DO UPDATE and editing one secretly edits the others.
The same id legitimately appearing once per page is how exercises move between pages, so only
repeats within the same page are remapped. The duplicate’s whole subtree (slides, tasks and
any custom peer-review config/questions) is remapped consistently. Occurrences are matched in
document order, which normalizeDocument guarantees is identical across the content and the
flat exercise/slide/task lists.
Returns a map from each regenerated duplicate’s new exercise id to its original id, so callers can recover data still keyed by the original id (e.g. custom peer-review config/questions).
Trait Implementations§
Source§impl Clone for CmsPageUpdate
impl Clone for CmsPageUpdate
Source§fn clone(&self) -> CmsPageUpdate
fn clone(&self) -> CmsPageUpdate
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl ComposeSchema for CmsPageUpdate
impl ComposeSchema for CmsPageUpdate
Source§impl Debug for CmsPageUpdate
impl Debug for CmsPageUpdate
Source§impl<'de> Deserialize<'de> for CmsPageUpdate
impl<'de> Deserialize<'de> for CmsPageUpdate
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<'a, R: Row> FromRow<'a, R> for CmsPageUpdatewhere
&'a str: ColumnIndex<R>,
Vec<GutenbergBlock>: Decode<'a, R::Database> + Type<R::Database>,
Vec<CmsPageExercise>: Decode<'a, R::Database> + Type<R::Database>,
Vec<CmsPageExerciseSlide>: Decode<'a, R::Database> + Type<R::Database>,
Vec<CmsPageExerciseTask>: Decode<'a, R::Database> + Type<R::Database>,
String: Decode<'a, R::Database> + Type<R::Database>,
Option<Uuid>: Decode<'a, R::Database> + Type<R::Database>,
bool: Decode<'a, R::Database> + Type<R::Database>,
impl<'a, R: Row> FromRow<'a, R> for CmsPageUpdatewhere
&'a str: ColumnIndex<R>,
Vec<GutenbergBlock>: Decode<'a, R::Database> + Type<R::Database>,
Vec<CmsPageExercise>: Decode<'a, R::Database> + Type<R::Database>,
Vec<CmsPageExerciseSlide>: Decode<'a, R::Database> + Type<R::Database>,
Vec<CmsPageExerciseTask>: Decode<'a, R::Database> + Type<R::Database>,
String: Decode<'a, R::Database> + Type<R::Database>,
Option<Uuid>: Decode<'a, R::Database> + Type<R::Database>,
bool: Decode<'a, R::Database> + Type<R::Database>,
Source§impl PartialEq for CmsPageUpdate
impl PartialEq for CmsPageUpdate
Source§impl Serialize for CmsPageUpdate
impl Serialize for CmsPageUpdate
Source§impl ToSchema for CmsPageUpdate
impl ToSchema for CmsPageUpdate
impl StructuralPartialEq for CmsPageUpdate
Auto Trait Implementations§
impl Freeze for CmsPageUpdate
impl RefUnwindSafe for CmsPageUpdate
impl Send for CmsPageUpdate
impl Sync for CmsPageUpdate
impl Unpin for CmsPageUpdate
impl UnsafeUnpin for CmsPageUpdate
impl UnwindSafe for CmsPageUpdate
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].