pub struct GenericCrudService<E, C, U, R>{ /* private fields */ }Expand description
A fully generic CRUD service.
Type parameters:
E— entity type (must implementPersistentEntity)C— create DTO (entity implementsFromCreateDto<C>)U— update DTO (entity implementsApplyUpdateDto<U>)R— repository (implementsCrudRepository<E>)
The service always holds an Arc<dyn CrudEventPublisher<E>>. When no
publisher is needed, NoOpCrudEventPublisher is used (zero overhead).
Event-publish errors are fire-and-forget — they never fail the operation.
Implementations§
Source§impl<E, C, U, R> GenericCrudService<E, C, U, R>where
E: PersistentEntity + Clone + FromCreateDto<C> + ApplyUpdateDto<U>,
C: Send + Sync + 'static,
U: Send + Sync + 'static,
R: CrudRepository<E>,
impl<E, C, U, R> GenericCrudService<E, C, U, R>where
E: PersistentEntity + Clone + FromCreateDto<C> + ApplyUpdateDto<U>,
C: Send + Sync + 'static,
U: Send + Sync + 'static,
R: CrudRepository<E>,
Sourcepub fn new(
repository: Arc<R>,
lifecycle: Arc<dyn ServiceLifecycle<E>>,
event_publisher: Arc<dyn CrudEventPublisher<E>>,
) -> Self
pub fn new( repository: Arc<R>, lifecycle: Arc<dyn ServiceLifecycle<E>>, event_publisher: Arc<dyn CrudEventPublisher<E>>, ) -> Self
Full constructor — supply all three dependencies.
Sourcepub fn with_guard(self, guard: Arc<dyn WriteGuard<E>>) -> Self
pub fn with_guard(self, guard: Arc<dyn WriteGuard<E>>) -> Self
Check every write against guard: its refusals refuse the write, its
shadowed violations are logged and the write proceeds.
Sourcepub fn with_write_hooks(self, hooks: Arc<dyn WriteHooks<E>>) -> Self
pub fn with_write_hooks(self, hooks: Arc<dyn WriteHooks<E>>) -> Self
Run hooks inside every write’s transaction, before and after the repository write (see
crate::write_hooks). Declared events are staged by the hooks the schema generator
emits for a model.
Sourcepub fn with_lifecycle(
repository: Arc<R>,
lifecycle: Arc<dyn ServiceLifecycle<E>>,
) -> Self
pub fn with_lifecycle( repository: Arc<R>, lifecycle: Arc<dyn ServiceLifecycle<E>>, ) -> Self
Create with a custom lifecycle and the no-op event publisher.
Sourcepub fn with_repository(repository: Arc<R>) -> Self
pub fn with_repository(repository: Arc<R>) -> Self
Create with the no-op lifecycle and no-op event publisher (generated default).
Sourcepub fn with_event_publisher(
self,
publisher: Arc<dyn CrudEventPublisher<E>>,
) -> Self
pub fn with_event_publisher( self, publisher: Arc<dyn CrudEventPublisher<E>>, ) -> Self
Replace the event publisher on an existing service (builder pattern).
Sourcepub fn repository(&self) -> &R
pub fn repository(&self) -> &R
Access the underlying repository for custom query extensions.
pub async fn list( &self, page: u32, limit: u32, filters: HashMap<String, String>, ) -> ServiceResult<(Vec<E>, u64)>
Sourcepub async fn list_with_info(
&self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> ServiceResult<(Vec<E>, PaginationInfo)>
pub async fn list_with_info( &self, page: u32, limit: u32, filters: HashMap<String, String>, ) -> ServiceResult<(Vec<E>, PaginationInfo)>
list, carrying the pagination info (cursor positions included) so
the HTTP layer can surface keyset paging on every generic route.
Sourcepub async fn aggregate(
&self,
spec: &AggregateSpec,
filters: HashMap<String, String>,
) -> ServiceResult<AggregateResult>
pub async fn aggregate( &self, spec: &AggregateSpec, filters: HashMap<String, String>, ) -> ServiceResult<AggregateResult>
Group and reduce the rows list would return, under the same filters.
pub async fn create(&self, dto: C) -> ServiceResult<E>
pub async fn get_by_id(&self, id: &str) -> ServiceResult<Option<E>>
pub async fn update(&self, id: &str, dto: U) -> ServiceResult<Option<E>>
pub async fn soft_delete(&self, id: &str) -> ServiceResult<bool>
pub async fn restore(&self, id: &str) -> ServiceResult<Option<E>>
pub async fn hard_delete(&self, id: &str) -> ServiceResult<bool>
pub async fn list_deleted( &self, page: u32, limit: u32, ) -> ServiceResult<(Vec<E>, u64)>
Sourcepub async fn empty_trash(&self) -> ServiceResult<u64>
pub async fn empty_trash(&self) -> ServiceResult<u64>
Permanently delete everything in the trash (atomic).
The trashed rows are loaded first, at most MAX_BATCH_SIZE of them (a larger trash is
refused: empty it in batches by id), and the write guard and lifecycle are asked about
each one as a single permanent delete would. The delete then names exactly those ids and
rolls back unless every one is still in the trash, so a row trashed after the check is
never deleted unchecked.
pub async fn count(&self) -> ServiceResult<u64>
pub async fn count_active(&self) -> ServiceResult<u64>
Sourcepub async fn find_by_id(&self, id: &str) -> ServiceResult<Option<E>>
pub async fn find_by_id(&self, id: &str) -> ServiceResult<Option<E>>
Alias for get_by_id — used by generated handlers.
Sourcepub async fn permanent_delete(&self, id: &str) -> ServiceResult<bool>
pub async fn permanent_delete(&self, id: &str) -> ServiceResult<bool>
Alias for hard_delete — used by generated handlers.
Sourcepub async fn count_deleted(&self) -> ServiceResult<u64>
pub async fn count_deleted(&self) -> ServiceResult<u64>
Count soft-deleted entities.
Sourcepub async fn get_deleted_by_id(&self, id: &str) -> ServiceResult<Option<E>>
pub async fn get_deleted_by_id(&self, id: &str) -> ServiceResult<Option<E>>
Retrieve a soft-deleted entity by ID (includes deleted records).
Sourcepub async fn list_deleted_filtered(
&self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> ServiceResult<(Vec<E>, u64)>
pub async fn list_deleted_filtered( &self, page: u32, limit: u32, filters: HashMap<String, String>, ) -> ServiceResult<(Vec<E>, u64)>
List deleted entities with the same filters and search the active list takes.
Sourcepub async fn upsert(&self, dto: C) -> ServiceResult<E>
pub async fn upsert(&self, dto: C) -> ServiceResult<E>
Upsert is not available on the generic service, and refuses rather than guessing.
An upsert must match the record it would update, by id or by a natural key. A create DTO carries no id and the framework knows no natural key for an entity, so the only thing this could do is create — which is what it used to do, silently duplicating the record on every retry. The generic HTTP route answers 501 for the same reason. An entity with a real upsert implements it in its own service.
Sourcepub async fn partial_update(
&self,
id: &str,
fields: HashMap<String, Value>,
) -> ServiceResult<Option<E>>where
E: Serialize + DeserializeOwned,
pub async fn partial_update(
&self,
id: &str,
fields: HashMap<String, Value>,
) -> ServiceResult<Option<E>>where
E: Serialize + DeserializeOwned,
Apply a partial update from a JSON map of field values.
Fields not present in the map are left unchanged. A key the entity does not have, or a new value for a protected field, refuses the whole write.
Sourcepub async fn bulk_create(&self, dtos: Vec<C>) -> ServiceResult<Vec<E>>where
E: FromCreateDto<C>,
pub async fn bulk_create(&self, dtos: Vec<C>) -> ServiceResult<Vec<E>>where
E: FromCreateDto<C>,
Create many entities, all or nothing.
Each item goes through what a single create does — the DTO conversion, the write guard,
the before_create hook — before anything is written; then the repository inserts them
in one transaction. A failure anywhere fails the whole batch and names the item: a
violation’s path starts with the item’s index (3/name).
Sourcepub async fn bulk_soft_delete(&self, ids: Vec<String>) -> ServiceResult<u64>
pub async fn bulk_soft_delete(&self, ids: Vec<String>) -> ServiceResult<u64>
Soft-delete many entities by id (atomic).
Sourcepub async fn bulk_restore(&self, ids: Vec<String>) -> ServiceResult<Vec<E>>
pub async fn bulk_restore(&self, ids: Vec<String>) -> ServiceResult<Vec<E>>
Restore many soft-deleted entities by id (atomic).
Sourcepub async fn restore_all(&self) -> ServiceResult<u64>
pub async fn restore_all(&self) -> ServiceResult<u64>
Restore every soft-deleted entity (atomic). Returns the number restored.
Emits a Restored event per entity, mirroring bulk_restore.
Like empty_trash, the trashed rows are loaded first (at most
MAX_BATCH_SIZE), each is put to the write guard and lifecycle as a single restore
would be, and the restore names exactly those ids, all or nothing.
Sourcepub async fn bulk_permanent_delete(
&self,
ids: Vec<String>,
) -> ServiceResult<u64>
pub async fn bulk_permanent_delete( &self, ids: Vec<String>, ) -> ServiceResult<u64>
Permanently delete many soft-deleted entities by id (atomic).
Sourcepub async fn bulk_update(
&self,
items: Vec<(String, U)>,
) -> ServiceResult<Vec<E>>
pub async fn bulk_update( &self, items: Vec<(String, U)>, ) -> ServiceResult<Vec<E>>
Full-update many entities (atomic). Each item is (id, UpdateDto).
Sourcepub async fn bulk_partial_update(
&self,
items: Vec<(String, HashMap<String, Value>)>,
) -> ServiceResult<Vec<E>>where
E: Serialize + DeserializeOwned,
pub async fn bulk_partial_update(
&self,
items: Vec<(String, HashMap<String, Value>)>,
) -> ServiceResult<Vec<E>>where
E: Serialize + DeserializeOwned,
Partial-update many entities (atomic). Each item is (id, field_map).
Sourcepub async fn preview_bulk_partial_update(
&self,
items: Vec<(String, HashMap<String, Value>)>,
) -> ServiceResult<Vec<BulkPreviewRow<E, ServiceError>>>where
E: Serialize + DeserializeOwned,
pub async fn preview_bulk_partial_update(
&self,
items: Vec<(String, HashMap<String, Value>)>,
) -> ServiceResult<Vec<BulkPreviewRow<E, ServiceError>>>where
E: Serialize + DeserializeOwned,
What bulk_partial_update would do, with
nothing written. Each row goes through the same steps the write takes —
it is found, the patch is merged and checked against the protected fields,
the write rules are consulted (quietly: a shadow rule logs on the real
write, not here) and the update hook runs — and its outcome is
kept instead of failing the batch, so one dialog can say which rows would
change and which would be refused. Only a batch that is too large or names
an id twice fails as a whole, as the write does.
Trait Implementations§
Source§impl<E, C, U, R> Clone for GenericCrudService<E, C, U, R>
impl<E, C, U, R> Clone for GenericCrudService<E, C, U, R>
Source§impl<E, C, U, R> CrudService<E, C, U> for GenericCrudService<E, C, U, R>where
E: PersistentEntity + Clone + Serialize + DeserializeOwned + FromCreateDto<C> + ApplyUpdateDto<U> + Send + Sync + 'static,
C: Send + Sync + 'static,
U: Send + Sync + 'static,
R: CrudRepository<E> + Send + Sync + 'static,
Blanket impl so that any GenericCrudService<E, C, U, R> automatically
satisfies CrudService<E, C, U> without generated adapter structs.
impl<E, C, U, R> CrudService<E, C, U> for GenericCrudService<E, C, U, R>where
E: PersistentEntity + Clone + Serialize + DeserializeOwned + FromCreateDto<C> + ApplyUpdateDto<U> + Send + Sync + 'static,
C: Send + Sync + 'static,
U: Send + Sync + 'static,
R: CrudRepository<E> + Send + Sync + 'static,
Blanket impl so that any GenericCrudService<E, C, U, R> automatically
satisfies CrudService<E, C, U> without generated adapter structs.
Generated code emits only a type alias:
pub type UserService = GenericCrudService<User, CreateUserDto, UpdateUserDto, UserRepository>;
That alias now directly implements CrudService and can be passed to
BackboneCrudHandler without any additional boilerplate.
Source§type Error = ServiceError
type Error = ServiceError
Source§fn violations_of(err: &ServiceError) -> Option<Vec<Violation>>
fn violations_of(err: &ServiceError) -> Option<Vec<Violation>>
None by default.Source§fn status_of(err: &ServiceError) -> Option<StatusCode>
fn status_of(err: &ServiceError) -> Option<StatusCode>
None (the default) leaves each route its own fallback: 422 when
violations_of names rules, else the route’s usual status.
GenericCrudService answers by variant (see service_error_status).Source§fn supports_upsert() -> bool
fn supports_upsert() -> bool
true by default, so a hand-written service
that implements one keeps its route; GenericCrudService answers false, and the
generic POST {resource}/upsert route then answers 501 rather than creating a duplicate.Source§fn entity_name() -> &'static str
fn entity_name() -> &'static str
?include= relations: fetch rows from table by id list, as JSON.
Default: no expansion. GenericCrudService delegates to its repository.Source§fn list<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn list_with_info<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, PaginationInfo), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_with_info<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, PaginationInfo), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
list, carrying the pagination info (cursor positions included) so
the HTTP layer can surface keyset paging. Default: the tuple form —
generated services override this with the repository’s cursors.Source§fn aggregate<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 AggregateSpec,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<AggregateResult, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn aggregate<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 AggregateSpec,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<AggregateResult, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
list would return, under the same filters. Read moreSource§fn table_name(&self) -> Option<&str>
fn table_name(&self) -> Option<&str>
Source§fn create<'life0, 'async_trait>(
&'life0 self,
dto: C,
) -> Pin<Box<dyn Future<Output = Result<E, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create<'life0, 'async_trait>(
&'life0 self,
dto: C,
) -> Pin<Box<dyn Future<Output = Result<E, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
dto: U,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
dto: U,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn partial_update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
fields: HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn partial_update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
fields: HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn bulk_create<'life0, 'async_trait>(
&'life0 self,
items: Vec<C>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_create<'life0, 'async_trait>(
&'life0 self,
items: Vec<C>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn upsert<'life0, 'async_trait>(
&'life0 self,
dto: C,
) -> Pin<Box<dyn Future<Output = Result<E, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert<'life0, 'async_trait>(
&'life0 self,
dto: C,
) -> Pin<Box<dyn Future<Output = Result<E, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn list_deleted<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_deleted<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn restore<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn restore<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn empty_trash<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn empty_trash<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_deleted_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_deleted_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn permanent_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn permanent_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn list_deleted_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_deleted_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<E>, u64), ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn count_active<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_active<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn count_deleted<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_deleted<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn bulk_soft_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_soft_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn bulk_restore<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_restore<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn bulk_permanent_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_permanent_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn restore_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn restore_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn bulk_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, U)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, U)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
(id, UpdateDto). Read moreSource§fn bulk_partial_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, HashMap<String, Value>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_partial_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, HashMap<String, Value>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<E>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
(id, field_map). Read moreSource§fn preview_bulk_partial_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, HashMap<String, Value>)>,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<BulkPreviewRow<E, ServiceError>>>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn preview_bulk_partial_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, HashMap<String, Value>)>,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<BulkPreviewRow<E, ServiceError>>>, ServiceError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
bulk_partial_update would do, with
nothing written: each row as it is and as it would become, or why the
write would refuse it. Ok(None) (the default) means this service has no
dry run, and the route says so instead of guessing. Read moreAuto Trait Implementations§
impl<E, C, U, R> !RefUnwindSafe for GenericCrudService<E, C, U, R>
impl<E, C, U, R> !UnwindSafe for GenericCrudService<E, C, U, R>
impl<E, C, U, R> Freeze for GenericCrudService<E, C, U, R>where
Arc<R>: Freeze,
Arc<dyn ServiceLifecycle<E>>: Freeze,
Arc<dyn CrudEventPublisher<E>>: Freeze,
Arc<dyn WriteGuard<E>>: Freeze,
Arc<dyn WriteHooks<E>>: Freeze,
PhantomData<(C, U)>: Freeze,
impl<E, C, U, R> Send for GenericCrudService<E, C, U, R>where
Arc<R>: Send,
Arc<dyn ServiceLifecycle<E>>: Send,
Arc<dyn CrudEventPublisher<E>>: Send,
Arc<dyn WriteGuard<E>>: Send,
Arc<dyn WriteHooks<E>>: Send,
PhantomData<(C, U)>: Send,
impl<E, C, U, R> Sync for GenericCrudService<E, C, U, R>where
Arc<R>: Sync,
Arc<dyn ServiceLifecycle<E>>: Sync,
Arc<dyn CrudEventPublisher<E>>: Sync,
Arc<dyn WriteGuard<E>>: Sync,
Arc<dyn WriteHooks<E>>: Sync,
PhantomData<(C, U)>: Sync,
impl<E, C, U, R> Unpin for GenericCrudService<E, C, U, R>where
Arc<R>: Unpin,
Arc<dyn ServiceLifecycle<E>>: Unpin,
Arc<dyn CrudEventPublisher<E>>: Unpin,
Arc<dyn WriteGuard<E>>: Unpin,
Arc<dyn WriteHooks<E>>: Unpin,
PhantomData<(C, U)>: Unpin,
impl<E, C, U, R> UnsafeUnpin for GenericCrudService<E, C, U, R>where
Arc<R>: UnsafeUnpin,
Arc<dyn ServiceLifecycle<E>>: UnsafeUnpin,
Arc<dyn CrudEventPublisher<E>>: UnsafeUnpin,
Arc<dyn WriteGuard<E>>: UnsafeUnpin,
Arc<dyn WriteHooks<E>>: UnsafeUnpin,
PhantomData<(C, U)>: UnsafeUnpin,
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> 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