use super::*; pub use shared_contracts::puzzle_clear::{ PuzzleClearActionRequest, PuzzleClearActionResponse, PuzzleClearActionType, PuzzleClearBoardCell, PuzzleClearBoardSnapshot, PuzzleClearCardAsset, PuzzleClearDraftResponse, PuzzleClearGenerationStatus, PuzzleClearImageAsset, PuzzleClearNextLevelRequest, PuzzleClearPatternGroup, PuzzleClearRetryLevelRequest, PuzzleClearRunResponse, PuzzleClearRunStatus, PuzzleClearRuntimeSnapshotResponse, PuzzleClearSessionResponse, PuzzleClearSessionSnapshotResponse, PuzzleClearStartRunRequest, PuzzleClearSwapRequest, PuzzleClearTimeUpRequest, PuzzleClearWorkDetailResponse, PuzzleClearWorkMutationResponse, PuzzleClearWorkProfileResponse, PuzzleClearWorkSummaryResponse, PuzzleClearWorksResponse, PuzzleClearWorkspaceCreateRequest, }; pub(crate) fn map_puzzle_clear_agent_session_procedure_result( result: PuzzleClearAgentSessionProcedureResult, ) -> Result { if !result.ok { return Err(SpacetimeClientError::procedure_failed(result.error_message)); } let session = result .session .ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle clear agent session 快照"))?; Ok(map_puzzle_clear_session_snapshot(session)) } pub(crate) fn map_puzzle_clear_work_procedure_result( result: PuzzleClearWorkProcedureResult, ) -> Result { if !result.ok { return Err(SpacetimeClientError::procedure_failed(result.error_message)); } let work = result .work .ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle clear work 快照"))?; Ok(map_puzzle_clear_work_snapshot(work)) } pub(crate) fn map_puzzle_clear_works_procedure_result( result: PuzzleClearWorksProcedureResult, ) -> Result, SpacetimeClientError> { if !result.ok { return Err(SpacetimeClientError::procedure_failed(result.error_message)); } Ok(result .items .into_iter() .map(map_puzzle_clear_work_snapshot) .collect()) } pub(crate) fn map_puzzle_clear_run_procedure_result( result: PuzzleClearRunProcedureResult, ) -> Result { if !result.ok { return Err(SpacetimeClientError::procedure_failed(result.error_message)); } let run = result .run .ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle clear run 快照"))?; Ok(map_puzzle_clear_run_snapshot(run)) } pub(crate) fn map_puzzle_clear_gallery_card_view_row( row: PuzzleClearGalleryCardViewRow, ) -> PuzzleClearWorkSummaryResponse { PuzzleClearWorkSummaryResponse { runtime_kind: "puzzle-clear".to_string(), work_id: row.work_id, profile_id: row.profile_id, owner_user_id: row.owner_user_id, source_session_id: None, work_title: row.work_title, work_description: row.work_description, theme_prompt: row.theme_prompt, cover_image_src: row.cover_image_src, publication_status: normalize_publication_status(&row.publication_status).to_string(), play_count: row.play_count, updated_at: format_timestamp_micros(row.updated_at_micros), published_at: row.published_at_micros.map(format_timestamp_micros), publish_ready: true, generation_status: parse_generation_status(&row.generation_status), } } fn map_puzzle_clear_session_snapshot( snapshot: PuzzleClearAgentSessionSnapshot, ) -> PuzzleClearSessionSnapshotResponse { PuzzleClearSessionSnapshotResponse { session_id: snapshot.session_id, owner_user_id: snapshot.owner_user_id, status: parse_generation_status(&snapshot.status), draft: snapshot.draft.map(map_puzzle_clear_draft_snapshot), created_at: format_timestamp_micros(snapshot.created_at_micros), updated_at: format_timestamp_micros(snapshot.updated_at_micros), } } fn map_puzzle_clear_work_snapshot( snapshot: PuzzleClearWorkSnapshot, ) -> PuzzleClearWorkProfileResponse { let atlas_asset = map_image_asset(snapshot.atlas_asset.clone()); let pattern_groups = snapshot .pattern_groups .clone() .into_iter() .map(map_pattern_group) .collect::>(); let card_assets = snapshot .card_assets .clone() .into_iter() .map(map_card_asset) .collect::>(); let board_background_asset = snapshot.board_background_asset.clone().map(map_image_asset); let draft = PuzzleClearDraftResponse { template_id: "puzzle-clear".to_string(), template_name: "拼消消".to_string(), profile_id: Some(snapshot.profile_id.clone()), work_title: snapshot.work_title.clone(), work_description: snapshot.work_description.clone(), theme_prompt: snapshot.theme_prompt.clone(), board_background_prompt: snapshot.board_background_prompt.clone(), generate_board_background: snapshot.generate_board_background, board_background_asset: board_background_asset.clone(), card_back_image_src: snapshot.card_back_image_src.clone(), atlas_asset: Some(atlas_asset.clone()), pattern_groups: pattern_groups.clone(), card_assets: card_assets.clone(), generation_status: parse_generation_status(&snapshot.generation_status), }; PuzzleClearWorkProfileResponse { summary: PuzzleClearWorkSummaryResponse { runtime_kind: "puzzle-clear".to_string(), work_id: snapshot.work_id, profile_id: snapshot.profile_id, owner_user_id: snapshot.owner_user_id, source_session_id: empty_string_to_none(snapshot.source_session_id), work_title: snapshot.work_title, work_description: snapshot.work_description, theme_prompt: snapshot.theme_prompt, cover_image_src: snapshot.cover_image_src, publication_status: normalize_publication_status(&snapshot.publication_status) .to_string(), play_count: snapshot.play_count, updated_at: format_timestamp_micros(snapshot.updated_at_micros), published_at: snapshot.published_at_micros.map(format_timestamp_micros), publish_ready: snapshot.publish_ready, generation_status: parse_generation_status(&snapshot.generation_status), }, draft, board_background_asset, atlas_asset, pattern_groups, card_assets, } } fn map_puzzle_clear_draft_snapshot(snapshot: PuzzleClearDraftSnapshot) -> PuzzleClearDraftResponse { PuzzleClearDraftResponse { template_id: snapshot.template_id, template_name: snapshot.template_name, profile_id: snapshot.profile_id, work_title: snapshot.work_title, work_description: snapshot.work_description, theme_prompt: snapshot.theme_prompt, board_background_prompt: snapshot.board_background_prompt, generate_board_background: snapshot.generate_board_background, board_background_asset: snapshot.board_background_asset.map(map_image_asset), card_back_image_src: snapshot.card_back_image_src, atlas_asset: snapshot.atlas_asset.map(map_image_asset), pattern_groups: snapshot .pattern_groups .into_iter() .map(map_pattern_group) .collect(), card_assets: snapshot .card_assets .into_iter() .map(map_card_asset) .collect(), generation_status: parse_generation_status(&snapshot.generation_status), } } fn map_image_asset(snapshot: PuzzleClearImageAssetSnapshot) -> PuzzleClearImageAsset { PuzzleClearImageAsset { asset_id: snapshot.asset_id, image_src: snapshot.image_src, image_object_key: snapshot.image_object_key, asset_object_id: snapshot.asset_object_id, generation_provider: snapshot.generation_provider, prompt: snapshot.prompt, width: snapshot.width, height: snapshot.height, } } fn map_pattern_group(snapshot: PuzzleClearPatternGroupSnapshot) -> PuzzleClearPatternGroup { PuzzleClearPatternGroup { group_id: snapshot.group_id, shape: snapshot.shape, width: snapshot.width, height: snapshot.height, atlas_x: snapshot.atlas_x, atlas_y: snapshot.atlas_y, atlas_width: snapshot.atlas_width, atlas_height: snapshot.atlas_height, } } fn map_card_asset(snapshot: PuzzleClearCardAssetSnapshot) -> PuzzleClearCardAsset { PuzzleClearCardAsset { card_id: snapshot.card_id, group_id: snapshot.group_id, shape: snapshot.shape, orientation: snapshot.orientation, part_x: snapshot.part_x, part_y: snapshot.part_y, image_src: snapshot.image_src, image_object_key: snapshot.image_object_key, asset_object_id: snapshot.asset_object_id, source_atlas_cell: snapshot.source_atlas_cell, } } fn map_puzzle_clear_run_snapshot( snapshot: PuzzleClearRuntimeSnapshot, ) -> PuzzleClearRuntimeSnapshotResponse { PuzzleClearRuntimeSnapshotResponse { run_id: snapshot.run_id, profile_id: snapshot.profile_id, owner_user_id: snapshot.owner_user_id, runtime_mode: None, status: parse_run_status(&snapshot.status), level_index: snapshot.level_index, clears_done: snapshot.clears_done, target_clears: snapshot.target_clears, level_duration_seconds: snapshot.level_duration_seconds, level_started_at_ms: snapshot.level_started_at_ms, board: PuzzleClearBoardSnapshot { rows: snapshot.board.rows, cols: snapshot.board.cols, cells: snapshot .board .cells .into_iter() .map(|cell| PuzzleClearBoardCell { row: cell.row, col: cell.col, card: cell.card.map(map_card_asset), locked_group_id: cell.locked_group_id, }) .collect(), }, ready_columns: snapshot .ready_columns .into_iter() .map(|column| column.into_iter().map(map_card_asset).collect()) .collect(), started_at_ms: snapshot.started_at_ms, finished_at_ms: snapshot.finished_at_ms, } } fn parse_generation_status(value: &str) -> PuzzleClearGenerationStatus { match value { "generating" => PuzzleClearGenerationStatus::Generating, "ready" => PuzzleClearGenerationStatus::Ready, "failed" => PuzzleClearGenerationStatus::Failed, _ => PuzzleClearGenerationStatus::Draft, } } fn parse_run_status(value: &str) -> PuzzleClearRunStatus { match value { "level_failed" => PuzzleClearRunStatus::LevelFailed, "level_cleared" => PuzzleClearRunStatus::LevelCleared, "finished" => PuzzleClearRunStatus::Finished, _ => PuzzleClearRunStatus::Playing, } } fn normalize_publication_status(value: &str) -> &str { match value { "Published" | "published" => "published", _ => "draft", } }