8abeb333bb
- 使用白名单控制快速编辑功能的显示 - 同步浮动工具栏、右键菜单、打开入口和提交门禁 - 禁用角色动作序列帧(整体)、音频和单个图标(explain: backend reject)的快速编辑 - 把快速编辑api改为只接受resource Id | asset Id,删除 image_src 参数, 以保证校验 其中包含生产数据迁移。迁移用于清理历史普通图片错误持久化的 assetKind="image",覆盖 asset → project-resource → showcase → canvas 四个作用域,并包含 operator 鉴权、分批 dry-run、批次 SHA-256 绑定 apply、active 结构化画 > 布迁移摘要同步及最终零残留复核。 --------- Co-authored-by: kdletters <kdletters@qq.com> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/140 Co-authored-by: 王德宇 <kvtodev@outlook.com> Co-committed-by: 王德宇 <kvtodev@outlook.com>
1873 lines
69 KiB
Rust
1873 lines
69 KiB
Rust
use super::*;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct EditorGenerationTargetPreflightRecordInput {
|
|
pub owner_user_id: String,
|
|
pub project_id: Option<String>,
|
|
pub asset_folder_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct EditorPixelArtCanvasPlaceholderRecordInput {
|
|
pub x: f64,
|
|
pub y: f64,
|
|
pub width: f64,
|
|
pub height: f64,
|
|
pub original_width: f64,
|
|
pub original_height: f64,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct EditorPixelArtCanvasCompletionRecordInput {
|
|
pub dialog_id: String,
|
|
pub title: String,
|
|
pub placeholder: EditorPixelArtCanvasPlaceholderRecordInput,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct EditorPixelArtResultPreflightRecordInput {
|
|
pub owner_user_id: String,
|
|
pub project_id: String,
|
|
pub asset_folder_id: String,
|
|
pub project_resource: EditorProjectResourceCreateRecordInput,
|
|
pub canvas_completion: EditorPixelArtCanvasCompletionRecordInput,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct EditorPixelArtResultPersistRecordInput {
|
|
pub owner_user_id: String,
|
|
pub project_id: String,
|
|
pub operation_id: String,
|
|
pub operation_fingerprint: String,
|
|
pub asset_object: module_assets::AssetObjectUpsertInput,
|
|
pub project_resource: EditorProjectResourceCreateRecordInput,
|
|
pub asset: EditorAssetCreateRecordInput,
|
|
pub canvas_completion: EditorPixelArtCanvasCompletionRecordInput,
|
|
pub completed_at_micros: i64,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct EditorPixelArtResultPersistRecord {
|
|
pub asset_object: module_assets::AssetObjectUpsertSnapshot,
|
|
pub project_resource: EditorProjectResourceRecord,
|
|
pub asset: EditorAssetRecord,
|
|
pub project: Option<EditorProjectRecord>,
|
|
}
|
|
|
|
impl From<EditorPixelArtCanvasPlaceholderRecordInput>
|
|
for crate::module_bindings::EditorPixelArtCanvasPlaceholderInput
|
|
{
|
|
fn from(input: EditorPixelArtCanvasPlaceholderRecordInput) -> Self {
|
|
Self {
|
|
x: input.x,
|
|
y: input.y,
|
|
width: input.width,
|
|
height: input.height,
|
|
original_width: input.original_width,
|
|
original_height: input.original_height,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<EditorGenerationTargetPreflightRecordInput>
|
|
for crate::module_bindings::EditorGenerationTargetPreflightInput
|
|
{
|
|
fn from(input: EditorGenerationTargetPreflightRecordInput) -> Self {
|
|
Self {
|
|
owner_user_id: input.owner_user_id,
|
|
project_id: input.project_id,
|
|
asset_folder_id: input.asset_folder_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<EditorPixelArtCanvasCompletionRecordInput>
|
|
for crate::module_bindings::EditorPixelArtCanvasCompletionInput
|
|
{
|
|
fn from(input: EditorPixelArtCanvasCompletionRecordInput) -> Self {
|
|
Self {
|
|
dialog_id: input.dialog_id,
|
|
title: input.title,
|
|
placeholder: input.placeholder.into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<EditorPixelArtResultPreflightRecordInput>
|
|
for crate::module_bindings::EditorPixelArtResultPreflightInput
|
|
{
|
|
fn from(input: EditorPixelArtResultPreflightRecordInput) -> Self {
|
|
Self {
|
|
owner_user_id: input.owner_user_id,
|
|
project_id: input.project_id,
|
|
asset_folder_id: input.asset_folder_id,
|
|
project_resource: input.project_resource.into(),
|
|
canvas_completion: input.canvas_completion.into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<EditorPixelArtResultPersistRecordInput>
|
|
for crate::module_bindings::EditorPixelArtResultPersistInput
|
|
{
|
|
fn from(input: EditorPixelArtResultPersistRecordInput) -> Self {
|
|
Self {
|
|
owner_user_id: input.owner_user_id,
|
|
project_id: input.project_id,
|
|
operation_id: input.operation_id,
|
|
operation_fingerprint: input.operation_fingerprint,
|
|
asset_object: input.asset_object.into(),
|
|
project_resource: input.project_resource.into(),
|
|
asset: input.asset.into(),
|
|
canvas_completion: input.canvas_completion.into(),
|
|
completed_at_micros: input.completed_at_micros,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct EditorSpritesheetSlicePersistItemRecordInput {
|
|
pub asset_object: module_assets::AssetObjectUpsertInput,
|
|
pub project_resource: Option<EditorProjectResourceCreateRecordInput>,
|
|
pub asset: Option<EditorAssetCreateRecordInput>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct EditorSpritesheetSliceBatchPersistRecordInput {
|
|
pub owner_user_id: String,
|
|
pub task_id: String,
|
|
pub group_task_id: Option<String>,
|
|
pub expected_asset_count: u32,
|
|
pub items: Vec<EditorSpritesheetSlicePersistItemRecordInput>,
|
|
pub completed_at_micros: i64,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct EditorSpritesheetSlicePersistedItemRecord {
|
|
pub asset_object: module_assets::AssetObjectUpsertSnapshot,
|
|
pub project_resource: Option<EditorProjectResourceRecord>,
|
|
pub asset: Option<EditorAssetRecord>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct EditorSpritesheetSliceBatchPersistRecord {
|
|
pub items: Vec<EditorSpritesheetSlicePersistedItemRecord>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct EditorGenerationResultPersistItemRecordInput {
|
|
pub slot: String,
|
|
pub asset_object: Option<module_assets::AssetObjectUpsertInput>,
|
|
pub project_resource: Option<EditorProjectResourceCreateRecordInput>,
|
|
pub asset: Option<EditorAssetCreateRecordInput>,
|
|
pub binding: Option<module_assets::AssetEntityBindingInput>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct EditorGenerationResultPersistRecordInput {
|
|
pub owner_user_id: String,
|
|
pub operation_kind: String,
|
|
pub operation_id: String,
|
|
pub operation_fingerprint: String,
|
|
pub items: Vec<EditorGenerationResultPersistItemRecordInput>,
|
|
pub canvas_layout: Option<EditorProjectLayoutSaveV2RecordInput>,
|
|
pub job_completion: Option<ExternalGenerationJobCompleteRecordInput>,
|
|
pub completed_at_micros: i64,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub enum EditorGenerationResultPersistStatusRecord {
|
|
Applied,
|
|
AlreadyApplied,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct EditorGenerationResultPersistedItemRecord {
|
|
pub slot: String,
|
|
pub asset_object: Option<module_assets::AssetObjectUpsertSnapshot>,
|
|
pub project_resource: Option<EditorProjectResourceRecord>,
|
|
pub asset: Option<EditorAssetRecord>,
|
|
pub binding: Option<module_assets::AssetEntityBindingSnapshot>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct EditorGenerationResultPersistRecord {
|
|
pub status: EditorGenerationResultPersistStatusRecord,
|
|
pub items: Vec<EditorGenerationResultPersistedItemRecord>,
|
|
pub project: Option<EditorProjectRecord>,
|
|
pub job: Option<ExternalGenerationJobRecord>,
|
|
}
|
|
|
|
impl From<EditorSpritesheetSlicePersistItemRecordInput>
|
|
for crate::module_bindings::EditorSpritesheetSlicePersistItemInput
|
|
{
|
|
fn from(input: EditorSpritesheetSlicePersistItemRecordInput) -> Self {
|
|
Self {
|
|
asset_object: input.asset_object.into(),
|
|
project_resource: input.project_resource.map(Into::into),
|
|
asset: input.asset.map(Into::into),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<EditorSpritesheetSliceBatchPersistRecordInput>
|
|
for crate::module_bindings::EditorSpritesheetSliceBatchPersistInput
|
|
{
|
|
fn from(input: EditorSpritesheetSliceBatchPersistRecordInput) -> Self {
|
|
Self {
|
|
owner_user_id: input.owner_user_id,
|
|
task_id: input.task_id,
|
|
group_task_id: input.group_task_id,
|
|
expected_asset_count: input.expected_asset_count,
|
|
items: input.items.into_iter().map(Into::into).collect(),
|
|
completed_at_micros: input.completed_at_micros,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<EditorGenerationResultPersistItemRecordInput>
|
|
for crate::module_bindings::EditorGenerationResultPersistItemInput
|
|
{
|
|
fn from(input: EditorGenerationResultPersistItemRecordInput) -> Self {
|
|
Self {
|
|
slot: input.slot,
|
|
asset_object: input.asset_object.map(Into::into),
|
|
project_resource: input.project_resource.map(Into::into),
|
|
asset: input.asset.map(Into::into),
|
|
binding: input.binding.map(Into::into),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<EditorGenerationResultPersistRecordInput>
|
|
for crate::module_bindings::EditorGenerationResultPersistInput
|
|
{
|
|
fn from(input: EditorGenerationResultPersistRecordInput) -> Self {
|
|
Self {
|
|
owner_user_id: input.owner_user_id,
|
|
operation_kind: input.operation_kind,
|
|
operation_id: input.operation_id,
|
|
operation_fingerprint: input.operation_fingerprint,
|
|
items: input.items.into_iter().map(Into::into).collect(),
|
|
canvas_layout: input.canvas_layout.map(Into::into),
|
|
job_completion: input.job_completion.map(Into::into),
|
|
completed_at_micros: input.completed_at_micros,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SpacetimeClient {
|
|
pub async fn resolve_editor_reference(
|
|
&self,
|
|
input: EditorReferenceResolveRecordInput,
|
|
) -> Result<EditorReferenceRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
self.call_after_connect(
|
|
"resolve_editor_reference_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.resolve_editor_reference_and_return_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_reference_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn preflight_editor_generation_target(
|
|
&self,
|
|
input: EditorGenerationTargetPreflightRecordInput,
|
|
) -> Result<(), SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
self.call_after_connect(
|
|
"preflight_editor_generation_target_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.preflight_editor_generation_target_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_generation_target_preflight_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn preflight_editor_pixel_art_result(
|
|
&self,
|
|
input: EditorPixelArtResultPreflightRecordInput,
|
|
) -> Result<(), SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"preflight_editor_pixel_art_result_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.preflight_editor_pixel_art_result_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_pixel_art_result_preflight_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn persist_editor_pixel_art_result(
|
|
&self,
|
|
input: EditorPixelArtResultPersistRecordInput,
|
|
) -> Result<EditorPixelArtResultPersistRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"persist_editor_pixel_art_result_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.persist_editor_pixel_art_result_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_pixel_art_result_persist_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn persist_editor_spritesheet_slice_batch(
|
|
&self,
|
|
input: EditorSpritesheetSliceBatchPersistRecordInput,
|
|
) -> Result<EditorSpritesheetSliceBatchPersistRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"persist_editor_spritesheet_slice_batch_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.persist_editor_spritesheet_slice_batch_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_spritesheet_slice_batch_persist_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn persist_editor_generation_result(
|
|
&self,
|
|
input: EditorGenerationResultPersistRecordInput,
|
|
) -> Result<EditorGenerationResultPersistRecord, SpacetimeClientError> {
|
|
self.persist_editor_generation_result_with_dispatch(input, || {})
|
|
.await
|
|
}
|
|
|
|
pub async fn persist_editor_generation_result_with_dispatch<F>(
|
|
&self,
|
|
input: EditorGenerationResultPersistRecordInput,
|
|
on_dispatch: F,
|
|
) -> Result<EditorGenerationResultPersistRecord, SpacetimeClientError>
|
|
where
|
|
F: FnOnce() + Send + 'static,
|
|
{
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"persist_editor_generation_result_and_return",
|
|
move |connection, sender| {
|
|
on_dispatch();
|
|
connection
|
|
.procedures()
|
|
.persist_editor_generation_result_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_generation_result_persist_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn create_editor_project(
|
|
&self,
|
|
input: EditorProjectCreateRecordInput,
|
|
) -> Result<EditorProjectRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"create_editor_project_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.create_editor_project_and_return_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_required_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_recent_editor_project(
|
|
&self,
|
|
owner_user_id: String,
|
|
) -> Result<Option<EditorProjectRecord>, SpacetimeClientError> {
|
|
let procedure_input = EditorProjectGetRecentInput { owner_user_id };
|
|
|
|
self.call_after_connect(
|
|
"get_recent_editor_project_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.get_recent_editor_project_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_optional_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_editor_project(
|
|
&self,
|
|
input: EditorProjectGetRecordInput,
|
|
) -> Result<EditorProjectRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"get_editor_project_and_return",
|
|
move |connection, sender| {
|
|
connection.procedures().get_editor_project_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_required_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn list_editor_projects(
|
|
&self,
|
|
owner_user_id: String,
|
|
) -> Result<Vec<EditorProjectRecord>, SpacetimeClientError> {
|
|
let procedure_input = EditorProjectListInput { owner_user_id };
|
|
|
|
self.call_after_connect(
|
|
"list_editor_projects_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.list_editor_projects_and_return_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_list_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn rename_editor_project(
|
|
&self,
|
|
input: EditorProjectRenameRecordInput,
|
|
) -> Result<EditorProjectRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"rename_editor_project_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.rename_editor_project_and_return_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_required_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn delete_editor_project(
|
|
&self,
|
|
input: EditorProjectDeleteRecordInput,
|
|
) -> Result<String, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"delete_editor_project_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.delete_editor_project_and_return_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_delete_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn save_editor_project_layout(
|
|
&self,
|
|
input: EditorProjectLayoutSaveRecordInput,
|
|
) -> Result<EditorProjectRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"save_editor_project_layout_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.save_editor_project_layout_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_required_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn save_editor_project_layout_ack(
|
|
&self,
|
|
input: EditorProjectLayoutSaveRecordInput,
|
|
) -> Result<EditorProjectLayoutSaveAckRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"save_editor_project_layout_ack",
|
|
move |connection, sender| {
|
|
connection.procedures().save_editor_project_layout_ack_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_layout_save_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn save_editor_project_layout_v2_ack(
|
|
&self,
|
|
input: EditorProjectLayoutSaveV2RecordInput,
|
|
) -> Result<EditorProjectLayoutSaveV2AckRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"save_editor_project_layout_v_2_ack",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.save_editor_project_layout_v_2_ack_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_layout_save_v2_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn save_editor_project_layout_v2(
|
|
&self,
|
|
input: EditorProjectLayoutSaveV2RecordInput,
|
|
) -> Result<EditorProjectRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"save_editor_project_layout_v_2_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.save_editor_project_layout_v_2_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_required_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn create_editor_project_resource(
|
|
&self,
|
|
input: EditorProjectResourceCreateRecordInput,
|
|
) -> Result<EditorProjectResourceRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"create_editor_project_resource_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.create_editor_project_resource_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_resource_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn repair_editor_project_resource_media(
|
|
&self,
|
|
input: EditorProjectResourceMediaRepairRecordInput,
|
|
) -> Result<EditorProjectResourceRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"repair_editor_project_resource_media_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.repair_editor_project_resource_media_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_resource_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn update_editor_project_resource_showcase(
|
|
&self,
|
|
input: EditorProjectResourceShowcaseUpdateRecordInput,
|
|
) -> Result<EditorProjectResourceRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"update_editor_project_resource_showcase_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.update_editor_project_resource_showcase_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_resource_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn list_public_editor_project_resources(
|
|
&self,
|
|
input: EditorProjectResourcePublicShowcaseListRecordInput,
|
|
) -> Result<Vec<EditorProjectResourceRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"list_public_editor_project_resources_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.list_public_editor_project_resources_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_project_resource_list_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_editor_asset_library(
|
|
&self,
|
|
owner_user_id: String,
|
|
now_micros: i64,
|
|
) -> Result<EditorAssetLibraryRecord, SpacetimeClientError> {
|
|
let procedure_input = EditorAssetLibraryGetInput {
|
|
owner_user_id,
|
|
now_micros,
|
|
};
|
|
|
|
self.call_after_connect(
|
|
"get_editor_asset_library_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.get_editor_asset_library_and_return_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_library_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn admin_list_editor_assets(
|
|
&self,
|
|
input: AdminEditorAssetListRecordInput,
|
|
) -> Result<Vec<AdminEditorAssetRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"admin_list_editor_assets_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.admin_list_editor_assets_and_return_then(procedure_input, move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_admin_editor_asset_list_procedure_result);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn find_editor_asset_group_source(
|
|
&self,
|
|
input: EditorAssetGroupSourceLookupRecordInput,
|
|
) -> Result<Option<EditorAssetRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"find_editor_asset_group_source_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.find_editor_asset_group_source_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_optional_editor_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn create_editor_asset_folder(
|
|
&self,
|
|
input: EditorAssetFolderCreateRecordInput,
|
|
) -> Result<EditorAssetFolderRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"create_editor_asset_folder_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.create_editor_asset_folder_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_folder_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn update_editor_asset_folder(
|
|
&self,
|
|
input: EditorAssetFolderUpdateRecordInput,
|
|
) -> Result<EditorAssetFolderRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"update_editor_asset_folder_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.update_editor_asset_folder_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_folder_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn delete_editor_asset_folder(
|
|
&self,
|
|
input: EditorAssetFolderDeleteRecordInput,
|
|
) -> Result<EditorAssetLibraryRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"delete_editor_asset_folder_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.delete_editor_asset_folder_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_folder_library_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn create_editor_asset(
|
|
&self,
|
|
input: EditorAssetCreateRecordInput,
|
|
) -> Result<EditorAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"create_editor_asset_and_return",
|
|
move |connection, sender| {
|
|
connection.procedures().create_editor_asset_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn complete_editor_asset_group_cohort(
|
|
&self,
|
|
input: EditorAssetGroupCohortCompleteRecordInput,
|
|
) -> Result<EditorAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"complete_editor_asset_group_cohort_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.complete_editor_asset_group_cohort_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn update_editor_asset(
|
|
&self,
|
|
input: EditorAssetUpdateRecordInput,
|
|
) -> Result<EditorAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"update_editor_asset_and_return",
|
|
move |connection, sender| {
|
|
connection.procedures().update_editor_asset_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn repair_editor_asset_media(
|
|
&self,
|
|
input: EditorAssetMediaRepairRecordInput,
|
|
) -> Result<EditorAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"repair_editor_asset_media_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.repair_editor_asset_media_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn delete_editor_asset(
|
|
&self,
|
|
input: EditorAssetDeleteRecordInput,
|
|
) -> Result<EditorAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"delete_editor_asset_and_return",
|
|
move |connection, sender| {
|
|
connection.procedures().delete_editor_asset_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn submit_editor_showcase_asset(
|
|
&self,
|
|
input: EditorShowcaseAssetSubmitRecordInput,
|
|
) -> Result<EditorShowcaseAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"submit_editor_showcase_asset_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.submit_editor_showcase_asset_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn list_public_editor_showcase_assets(
|
|
&self,
|
|
input: EditorShowcaseAssetPublicListRecordInput,
|
|
) -> Result<Vec<EditorShowcaseAssetRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"list_public_editor_showcase_assets_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.list_public_editor_showcase_assets_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_list_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn list_public_editor_showcase_assets_for_viewer(
|
|
&self,
|
|
input: EditorShowcaseAssetViewerListRecordInput,
|
|
) -> Result<Vec<EditorShowcaseAssetViewerRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"list_public_editor_showcase_assets_for_viewer_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.list_public_editor_showcase_assets_for_viewer_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_viewer_list_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn admin_list_editor_showcase_assets(
|
|
&self,
|
|
input: EditorShowcaseAssetAdminListRecordInput,
|
|
) -> Result<Vec<EditorShowcaseAssetRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"admin_list_editor_showcase_assets_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.admin_list_editor_showcase_assets_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_list_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn admin_review_editor_showcase_asset(
|
|
&self,
|
|
input: EditorShowcaseAssetAdminReviewRecordInput,
|
|
) -> Result<EditorShowcaseAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"admin_review_editor_showcase_asset_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.admin_review_editor_showcase_asset_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn update_editor_showcase_asset_display(
|
|
&self,
|
|
input: EditorShowcaseAssetDisplayUpdateRecordInput,
|
|
) -> Result<EditorShowcaseAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"update_editor_showcase_asset_display_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.update_editor_showcase_asset_display_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn mark_editor_showcase_asset_refunded(
|
|
&self,
|
|
input: EditorShowcaseAssetRefundMarkRecordInput,
|
|
) -> Result<EditorShowcaseAssetRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"mark_editor_showcase_asset_refunded_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.mark_editor_showcase_asset_refunded_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn set_editor_showcase_asset_like_for_viewer(
|
|
&self,
|
|
input: EditorShowcaseAssetLikeToggleRecordInput,
|
|
) -> Result<EditorShowcaseAssetViewerRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"set_editor_showcase_asset_like_for_viewer_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.set_editor_showcase_asset_like_for_viewer_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_asset_viewer_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_editor_showcase_campaign_config(
|
|
&self,
|
|
input: EditorShowcaseCampaignConfigGetRecordInput,
|
|
) -> Result<Option<EditorShowcaseCampaignConfigRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"get_editor_showcase_campaign_config_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.get_editor_showcase_campaign_config_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_campaign_config_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn upsert_editor_showcase_campaign_config(
|
|
&self,
|
|
input: EditorShowcaseCampaignConfigUpsertRecordInput,
|
|
) -> Result<Option<EditorShowcaseCampaignConfigRecord>, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"upsert_editor_showcase_campaign_config_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.upsert_editor_showcase_campaign_config_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(map_editor_showcase_campaign_config_procedure_result);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_editor_generation_pricing_config(
|
|
&self,
|
|
) -> Result<Option<EditorGenerationPricingConfigRecord>, SpacetimeClientError> {
|
|
self.call_after_connect(
|
|
"get_editor_generation_pricing_config_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.get_editor_generation_pricing_config_and_return_then(move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(
|
|
map_editor_generation_pricing_config_optional_procedure_result,
|
|
);
|
|
send_once(&sender, mapped);
|
|
});
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn upsert_editor_generation_pricing_config(
|
|
&self,
|
|
input: EditorGenerationPricingConfigUpsertRecordInput,
|
|
) -> Result<EditorGenerationPricingConfigRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"upsert_editor_generation_pricing_config_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.upsert_editor_generation_pricing_config_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(
|
|
map_editor_generation_pricing_config_required_procedure_result,
|
|
);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn initialize_editor_generation_pricing_config_if_missing(
|
|
&self,
|
|
input: EditorGenerationPricingConfigUpsertRecordInput,
|
|
) -> Result<EditorGenerationPricingConfigRecord, SpacetimeClientError> {
|
|
let procedure_input = input.into();
|
|
|
|
self.call_after_connect(
|
|
"initialize_editor_generation_pricing_config_if_missing_and_return",
|
|
move |connection, sender| {
|
|
connection
|
|
.procedures()
|
|
.initialize_editor_generation_pricing_config_if_missing_and_return_then(
|
|
procedure_input,
|
|
move |_, result| {
|
|
let mapped = result
|
|
.map_err(SpacetimeClientError::from_sdk_error)
|
|
.and_then(
|
|
map_editor_generation_pricing_config_required_procedure_result,
|
|
);
|
|
send_once(&sender, mapped);
|
|
},
|
|
);
|
|
},
|
|
)
|
|
.await
|
|
}
|
|
}
|
|
|
|
fn map_editor_pixel_art_result_preflight_result(
|
|
result: crate::module_bindings::EditorPixelArtResultPreflightResult,
|
|
) -> Result<(), SpacetimeClientError> {
|
|
if result.ok {
|
|
return Ok(());
|
|
}
|
|
Err(SpacetimeClientError::procedure_failed(result.error_message))
|
|
}
|
|
|
|
fn map_editor_generation_target_preflight_result(
|
|
result: crate::module_bindings::EditorGenerationTargetPreflightResult,
|
|
) -> Result<(), SpacetimeClientError> {
|
|
if result.ok {
|
|
return Ok(());
|
|
}
|
|
Err(SpacetimeClientError::procedure_failed(result.error_message))
|
|
}
|
|
|
|
fn map_editor_pixel_art_result_persist_result(
|
|
result: crate::module_bindings::EditorPixelArtResultPersistResult,
|
|
) -> Result<EditorPixelArtResultPersistRecord, SpacetimeClientError> {
|
|
if !result.ok {
|
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
|
}
|
|
// 中文注释:三种落库状态(Applied / DialogMissing / AlreadyApplied)目前没有任何
|
|
// 上层消费方,不再向上透传;但状态缺失说明 procedure 返回体不完整,仍要拦在这里。
|
|
if result.status.is_none() {
|
|
return Err(SpacetimeClientError::validation_failed(
|
|
"完美像素持久化结果缺少状态",
|
|
));
|
|
}
|
|
let asset_object = result.asset_object.ok_or_else(|| {
|
|
SpacetimeClientError::validation_failed("完美像素持久化结果缺少 asset object")
|
|
})?;
|
|
let project_resource = result
|
|
.project_resource
|
|
.ok_or_else(|| SpacetimeClientError::validation_failed("完美像素持久化结果缺少项目资源"))?;
|
|
let asset = result
|
|
.asset
|
|
.ok_or_else(|| SpacetimeClientError::validation_failed("完美像素持久化结果缺少账号素材"))?;
|
|
let project = result
|
|
.project
|
|
.map(|project| {
|
|
map_editor_project_optional_procedure_result(
|
|
crate::module_bindings::EditorProjectProcedureResult {
|
|
ok: true,
|
|
project: Some(project),
|
|
error_message: None,
|
|
},
|
|
)
|
|
})
|
|
.transpose()?
|
|
.flatten();
|
|
|
|
Ok(EditorPixelArtResultPersistRecord {
|
|
asset_object: map_editor_spritesheet_asset_object_snapshot(asset_object),
|
|
project_resource: map_editor_spritesheet_project_resource_snapshot(project_resource)?,
|
|
asset: map_editor_spritesheet_asset_snapshot(asset)?,
|
|
project,
|
|
})
|
|
}
|
|
|
|
fn map_editor_spritesheet_slice_batch_persist_result(
|
|
result: crate::module_bindings::EditorSpritesheetSliceBatchPersistResult,
|
|
) -> Result<EditorSpritesheetSliceBatchPersistRecord, SpacetimeClientError> {
|
|
if !result.ok {
|
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
|
}
|
|
let items = result
|
|
.items
|
|
.into_iter()
|
|
.map(|item| {
|
|
Ok(EditorSpritesheetSlicePersistedItemRecord {
|
|
asset_object: map_editor_spritesheet_asset_object_snapshot(item.asset_object),
|
|
project_resource: item
|
|
.project_resource
|
|
.map(map_editor_spritesheet_project_resource_snapshot)
|
|
.transpose()?,
|
|
asset: item
|
|
.asset
|
|
.map(map_editor_spritesheet_asset_snapshot)
|
|
.transpose()?,
|
|
})
|
|
})
|
|
.collect::<Result<Vec<_>, SpacetimeClientError>>()?;
|
|
Ok(EditorSpritesheetSliceBatchPersistRecord { items })
|
|
}
|
|
|
|
fn map_editor_generation_result_persist_result(
|
|
result: crate::module_bindings::EditorGenerationResultPersistResult,
|
|
) -> Result<EditorGenerationResultPersistRecord, SpacetimeClientError> {
|
|
if !result.ok {
|
|
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
|
}
|
|
let status = match result
|
|
.status
|
|
.ok_or_else(|| SpacetimeClientError::validation_failed("编辑器生成结果原子提交缺少状态"))?
|
|
{
|
|
crate::module_bindings::EditorGenerationResultPersistStatus::Applied => {
|
|
EditorGenerationResultPersistStatusRecord::Applied
|
|
}
|
|
crate::module_bindings::EditorGenerationResultPersistStatus::AlreadyApplied => {
|
|
EditorGenerationResultPersistStatusRecord::AlreadyApplied
|
|
}
|
|
};
|
|
let items = result
|
|
.items
|
|
.into_iter()
|
|
.map(|item| {
|
|
Ok(EditorGenerationResultPersistedItemRecord {
|
|
slot: item.slot,
|
|
asset_object: item
|
|
.asset_object
|
|
.map(map_editor_spritesheet_asset_object_snapshot),
|
|
project_resource: item
|
|
.project_resource
|
|
.map(map_editor_spritesheet_project_resource_snapshot)
|
|
.transpose()?,
|
|
asset: item
|
|
.asset
|
|
.map(map_editor_spritesheet_asset_snapshot)
|
|
.transpose()?,
|
|
binding: item.binding.map(map_editor_generation_binding_snapshot),
|
|
})
|
|
})
|
|
.collect::<Result<Vec<_>, SpacetimeClientError>>()?;
|
|
let project = result
|
|
.project
|
|
.map(|project| {
|
|
map_editor_project_optional_procedure_result(
|
|
crate::module_bindings::EditorProjectProcedureResult {
|
|
ok: true,
|
|
project: Some(project),
|
|
error_message: None,
|
|
},
|
|
)
|
|
})
|
|
.transpose()?
|
|
.flatten();
|
|
let job = result.job.map(map_external_generation_job_snapshot);
|
|
|
|
Ok(EditorGenerationResultPersistRecord {
|
|
status,
|
|
items,
|
|
project,
|
|
job,
|
|
})
|
|
}
|
|
|
|
fn map_editor_generation_binding_snapshot(
|
|
snapshot: crate::module_bindings::AssetEntityBindingSnapshot,
|
|
) -> module_assets::AssetEntityBindingSnapshot {
|
|
module_assets::AssetEntityBindingSnapshot {
|
|
binding_id: snapshot.binding_id,
|
|
asset_object_id: snapshot.asset_object_id,
|
|
entity_kind: snapshot.entity_kind,
|
|
entity_id: snapshot.entity_id,
|
|
slot: snapshot.slot,
|
|
asset_kind: snapshot.asset_kind,
|
|
owner_user_id: snapshot.owner_user_id,
|
|
profile_id: snapshot.profile_id,
|
|
created_at_micros: snapshot.created_at_micros,
|
|
updated_at_micros: snapshot.updated_at_micros,
|
|
}
|
|
}
|
|
|
|
fn map_editor_spritesheet_asset_object_snapshot(
|
|
snapshot: crate::module_bindings::AssetObjectUpsertSnapshot,
|
|
) -> module_assets::AssetObjectUpsertSnapshot {
|
|
module_assets::AssetObjectUpsertSnapshot {
|
|
asset_object_id: snapshot.asset_object_id,
|
|
bucket: snapshot.bucket,
|
|
object_key: snapshot.object_key,
|
|
access_policy: match snapshot.access_policy {
|
|
crate::module_bindings::AssetObjectAccessPolicy::Private => {
|
|
module_assets::AssetObjectAccessPolicy::Private
|
|
}
|
|
crate::module_bindings::AssetObjectAccessPolicy::PublicRead => {
|
|
module_assets::AssetObjectAccessPolicy::PublicRead
|
|
}
|
|
},
|
|
content_type: snapshot.content_type,
|
|
content_length: snapshot.content_length,
|
|
content_hash: snapshot.content_hash,
|
|
version: snapshot.version,
|
|
source_job_id: snapshot.source_job_id,
|
|
owner_user_id: snapshot.owner_user_id,
|
|
profile_id: snapshot.profile_id,
|
|
entity_id: snapshot.entity_id,
|
|
asset_kind: snapshot.asset_kind,
|
|
created_at_micros: snapshot.created_at_micros,
|
|
updated_at_micros: snapshot.updated_at_micros,
|
|
}
|
|
}
|
|
|
|
fn map_editor_spritesheet_project_resource_snapshot(
|
|
snapshot: crate::module_bindings::EditorProjectResourceSnapshot,
|
|
) -> Result<EditorProjectResourceRecord, SpacetimeClientError> {
|
|
Ok(EditorProjectResourceRecord {
|
|
resource_id: snapshot.resource_id,
|
|
project_id: snapshot.project_id,
|
|
owner_user_id: snapshot.owner_user_id,
|
|
asset_object_id: snapshot.asset_object_id,
|
|
image_src: snapshot.image_src,
|
|
object_key: snapshot.object_key,
|
|
width: snapshot.width,
|
|
height: snapshot.height,
|
|
source_type: snapshot.source_type,
|
|
prompt: snapshot.prompt,
|
|
actual_prompt: snapshot.actual_prompt,
|
|
model: snapshot.model,
|
|
provider: snapshot.provider,
|
|
task_id: snapshot.task_id,
|
|
source_resource_id: snapshot.source_resource_id,
|
|
asset_kind: snapshot.asset_kind,
|
|
generation_inputs: parse_editor_spritesheet_generation_inputs(
|
|
snapshot.generation_inputs_json,
|
|
"图片画布图集切片资源生成输入 JSON",
|
|
)?,
|
|
image_sequence_frames: parse_editor_spritesheet_generation_inputs(
|
|
snapshot.image_sequence_frames_json,
|
|
"图片画布图集切片资源序列帧 JSON",
|
|
)?,
|
|
image_sequence_duration_ms: snapshot.image_sequence_duration_ms,
|
|
public_showcase_enabled: snapshot.public_showcase_enabled,
|
|
created_at: format_timestamp_micros(snapshot.created_at_micros),
|
|
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
|
})
|
|
}
|
|
|
|
fn map_editor_spritesheet_asset_snapshot(
|
|
snapshot: crate::module_bindings::EditorAssetSnapshot,
|
|
) -> Result<EditorAssetRecord, SpacetimeClientError> {
|
|
Ok(EditorAssetRecord {
|
|
asset_id: snapshot.asset_id,
|
|
folder_id: snapshot.folder_id,
|
|
label: snapshot.label,
|
|
asset_object_id: snapshot.asset_object_id,
|
|
image_src: snapshot.image_src,
|
|
object_key: snapshot.object_key,
|
|
width: snapshot.width,
|
|
height: snapshot.height,
|
|
source_type: snapshot.source_type,
|
|
prompt: snapshot.prompt,
|
|
actual_prompt: snapshot.actual_prompt,
|
|
model: snapshot.model,
|
|
provider: snapshot.provider,
|
|
task_id: snapshot.task_id,
|
|
asset_kind: snapshot.asset_kind,
|
|
generation_inputs: parse_editor_spritesheet_generation_inputs(
|
|
snapshot.generation_inputs_json,
|
|
"图片画布图集切片素材生成输入 JSON",
|
|
)?,
|
|
image_sequence_frames: parse_editor_spritesheet_generation_inputs(
|
|
snapshot.image_sequence_frames_json,
|
|
"图片画布图集切片素材序列帧 JSON",
|
|
)?,
|
|
image_sequence_duration_ms: snapshot.image_sequence_duration_ms,
|
|
source_resource_id: snapshot.source_resource_id,
|
|
public_showcase_enabled: snapshot.public_showcase_enabled,
|
|
thumbnail_src: snapshot.thumbnail_src,
|
|
generation_cost_mud_points: snapshot.generation_cost_mud_points,
|
|
showcase_id: snapshot.showcase_id,
|
|
showcase_review_status: snapshot.showcase_review_status,
|
|
showcase_display_enabled: snapshot.showcase_display_enabled,
|
|
showcase_like_count: snapshot.showcase_like_count,
|
|
created_at: format_timestamp_micros(snapshot.created_at_micros),
|
|
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
|
})
|
|
}
|
|
|
|
fn parse_editor_spritesheet_generation_inputs(
|
|
raw: Option<String>,
|
|
label: &str,
|
|
) -> Result<Option<serde_json::Value>, SpacetimeClientError> {
|
|
raw.map(|value| {
|
|
serde_json::from_str(&value).map_err(|error| {
|
|
SpacetimeClientError::validation_failed(format!("{label} 无法解析:{error}"))
|
|
})
|
|
})
|
|
.transpose()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod editor_generation_result_persist_mapper_tests {
|
|
use super::*;
|
|
|
|
fn empty_result(ok: bool) -> crate::module_bindings::EditorGenerationResultPersistResult {
|
|
crate::module_bindings::EditorGenerationResultPersistResult {
|
|
ok,
|
|
status: None,
|
|
items: Vec::new(),
|
|
project: None,
|
|
job: None,
|
|
error_message: None,
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn editor_generation_result_mapper_preserves_procedure_failure() {
|
|
let mut result = empty_result(false);
|
|
result.error_message = Some("事务提交失败".to_string());
|
|
|
|
let error = map_editor_generation_result_persist_result(result)
|
|
.expect_err("ok=false 必须保留 procedure 失败");
|
|
|
|
assert!(matches!(
|
|
error,
|
|
SpacetimeClientError::Procedure(message) if message == "事务提交失败"
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn editor_generation_result_mapper_requires_status() {
|
|
let error = map_editor_generation_result_persist_result(empty_result(true))
|
|
.expect_err("成功结果缺少状态时必须拒绝");
|
|
|
|
assert!(matches!(
|
|
error,
|
|
SpacetimeClientError::Runtime(message)
|
|
if message == "编辑器生成结果原子提交缺少状态"
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn editor_generation_result_mapper_preserves_apply_status() {
|
|
let cases = [
|
|
(
|
|
crate::module_bindings::EditorGenerationResultPersistStatus::Applied,
|
|
EditorGenerationResultPersistStatusRecord::Applied,
|
|
),
|
|
(
|
|
crate::module_bindings::EditorGenerationResultPersistStatus::AlreadyApplied,
|
|
EditorGenerationResultPersistStatusRecord::AlreadyApplied,
|
|
),
|
|
];
|
|
|
|
for (binding_status, expected) in cases {
|
|
let mut result = empty_result(true);
|
|
result.status = Some(binding_status);
|
|
let mapped =
|
|
map_editor_generation_result_persist_result(result).expect("完整状态应映射成功");
|
|
assert_eq!(mapped.status, expected);
|
|
assert!(mapped.items.is_empty());
|
|
assert!(mapped.project.is_none());
|
|
assert!(mapped.job.is_none());
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod pixel_art_persist_mapper_tests {
|
|
use super::*;
|
|
|
|
fn empty_pixel_art_persist_result(
|
|
ok: bool,
|
|
) -> crate::module_bindings::EditorPixelArtResultPersistResult {
|
|
crate::module_bindings::EditorPixelArtResultPersistResult {
|
|
ok,
|
|
status: None,
|
|
asset_object: None,
|
|
project_resource: None,
|
|
asset: None,
|
|
project: None,
|
|
error_message: None,
|
|
}
|
|
}
|
|
|
|
fn pixel_art_asset_object_snapshot() -> crate::module_bindings::AssetObjectUpsertSnapshot {
|
|
crate::module_bindings::AssetObjectUpsertSnapshot {
|
|
asset_object_id: "assetobj_pixel".to_string(),
|
|
bucket: "private".to_string(),
|
|
object_key: "editor/pixel.png".to_string(),
|
|
access_policy: crate::module_bindings::AssetObjectAccessPolicy::Private,
|
|
content_type: Some("image/png".to_string()),
|
|
content_length: 16,
|
|
content_hash: Some("output-sha256".to_string()),
|
|
version: 1,
|
|
source_job_id: Some("pixel-art-snap-dialog-1".to_string()),
|
|
owner_user_id: Some("user-1".to_string()),
|
|
profile_id: None,
|
|
entity_id: Some("project-1".to_string()),
|
|
asset_kind: "editor_pixel_art_snap".to_string(),
|
|
created_at_micros: 10,
|
|
updated_at_micros: 11,
|
|
}
|
|
}
|
|
|
|
fn pixel_art_project_resource_snapshot() -> crate::module_bindings::EditorProjectResourceSnapshot
|
|
{
|
|
crate::module_bindings::EditorProjectResourceSnapshot {
|
|
resource_id: "editor-resource-pixel".to_string(),
|
|
project_id: "project-1".to_string(),
|
|
owner_user_id: "user-1".to_string(),
|
|
asset_object_id: Some("assetobj_pixel".to_string()),
|
|
image_src: "/api/assets/assetobj_pixel/content".to_string(),
|
|
object_key: Some("editor/pixel.png".to_string()),
|
|
width: 32,
|
|
height: 32,
|
|
source_type: "perfect-pixel".to_string(),
|
|
prompt: None,
|
|
actual_prompt: None,
|
|
model: None,
|
|
provider: None,
|
|
task_id: Some("pixel-art-snap-dialog-1".to_string()),
|
|
source_resource_id: Some("source-resource".to_string()),
|
|
asset_kind: None,
|
|
generation_inputs_json: Some(r#"{"source":"canvas"}"#.to_string()),
|
|
public_showcase_enabled: false,
|
|
created_at_micros: 10,
|
|
updated_at_micros: 11,
|
|
image_sequence_frames_json: None,
|
|
image_sequence_duration_ms: None,
|
|
}
|
|
}
|
|
|
|
fn pixel_art_asset_snapshot() -> crate::module_bindings::EditorAssetSnapshot {
|
|
crate::module_bindings::EditorAssetSnapshot {
|
|
asset_id: "editor-asset-pixel".to_string(),
|
|
folder_id: "folder-1".to_string(),
|
|
label: "Pixel result".to_string(),
|
|
asset_object_id: Some("assetobj_pixel".to_string()),
|
|
image_src: "/api/assets/assetobj_pixel/content".to_string(),
|
|
object_key: Some("editor/pixel.png".to_string()),
|
|
width: 32,
|
|
height: 32,
|
|
source_type: "perfect-pixel".to_string(),
|
|
prompt: None,
|
|
actual_prompt: None,
|
|
model: None,
|
|
provider: None,
|
|
task_id: Some("pixel-art-snap-dialog-1".to_string()),
|
|
asset_kind: None,
|
|
generation_inputs_json: Some(r#"{"source":"canvas"}"#.to_string()),
|
|
source_resource_id: Some("source-resource".to_string()),
|
|
public_showcase_enabled: Some(false),
|
|
created_at_micros: 10,
|
|
updated_at_micros: 11,
|
|
thumbnail_src: None,
|
|
generation_cost_mud_points: 0,
|
|
showcase_id: None,
|
|
showcase_review_status: None,
|
|
showcase_display_enabled: None,
|
|
showcase_like_count: None,
|
|
group_task_id: None,
|
|
image_sequence_frames_json: None,
|
|
image_sequence_duration_ms: None,
|
|
}
|
|
}
|
|
|
|
fn successful_pixel_art_persist_result(
|
|
status: crate::module_bindings::EditorPixelArtResultPersistStatus,
|
|
) -> crate::module_bindings::EditorPixelArtResultPersistResult {
|
|
crate::module_bindings::EditorPixelArtResultPersistResult {
|
|
ok: true,
|
|
status: Some(status),
|
|
asset_object: Some(pixel_art_asset_object_snapshot()),
|
|
project_resource: Some(pixel_art_project_resource_snapshot()),
|
|
asset: Some(pixel_art_asset_snapshot()),
|
|
project: None,
|
|
error_message: None,
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn editor_pixel_art_persist_mapper_rejects_procedure_failure_before_snapshots() {
|
|
let mut result = empty_pixel_art_persist_result(false);
|
|
result.error_message = Some("事务提交失败".to_string());
|
|
|
|
let error = map_editor_pixel_art_result_persist_result(result)
|
|
.expect_err("ok=false 必须保留 procedure 失败");
|
|
|
|
assert!(matches!(
|
|
error,
|
|
SpacetimeClientError::Procedure(message) if message == "事务提交失败"
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn editor_pixel_art_persist_mapper_rejects_missing_required_snapshot() {
|
|
let mut result = empty_pixel_art_persist_result(true);
|
|
result.status = Some(crate::module_bindings::EditorPixelArtResultPersistStatus::Applied);
|
|
|
|
let error = map_editor_pixel_art_result_persist_result(result)
|
|
.expect_err("成功结果缺少 asset object 时必须拒绝");
|
|
|
|
assert!(matches!(
|
|
error,
|
|
SpacetimeClientError::Runtime(message)
|
|
if message == "完美像素持久化结果缺少 asset object"
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn editor_pixel_art_persist_mapper_rejects_missing_status() {
|
|
let mut result = successful_pixel_art_persist_result(
|
|
crate::module_bindings::EditorPixelArtResultPersistStatus::Applied,
|
|
);
|
|
result.status = None;
|
|
|
|
let error = map_editor_pixel_art_result_persist_result(result)
|
|
.expect_err("成功结果缺少状态时必须拒绝");
|
|
|
|
assert!(matches!(
|
|
error,
|
|
SpacetimeClientError::Runtime(message)
|
|
if message == "完美像素持久化结果缺少状态"
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn editor_pixel_art_persist_mapper_accepts_every_status_and_missing_project() {
|
|
let cases = [
|
|
crate::module_bindings::EditorPixelArtResultPersistStatus::Applied,
|
|
crate::module_bindings::EditorPixelArtResultPersistStatus::DialogMissing,
|
|
crate::module_bindings::EditorPixelArtResultPersistStatus::AlreadyApplied,
|
|
];
|
|
|
|
for binding_status in cases {
|
|
let mapped = map_editor_pixel_art_result_persist_result(
|
|
successful_pixel_art_persist_result(binding_status),
|
|
)
|
|
.expect("project=None 仍应映射成功");
|
|
|
|
assert_eq!(mapped.asset_object.asset_object_id, "assetobj_pixel");
|
|
assert_eq!(mapped.project_resource.resource_id, "editor-resource-pixel");
|
|
assert_eq!(mapped.asset.asset_id, "editor-asset-pixel");
|
|
assert!(mapped.project.is_none());
|
|
}
|
|
}
|
|
}
|