use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct CreateBigFishSessionRequest { #[serde(default)] pub seed_text: Option, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct SendBigFishMessageRequest { pub client_message_id: String, pub text: String, #[serde(default)] pub quick_fill_requested: Option, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct ExecuteBigFishActionRequest { pub action: String, #[serde(default)] pub level: Option, #[serde(default)] pub motion_key: Option, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct SubmitBigFishInputRequest { pub x: f32, pub y: f32, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct BigFishAnchorItemResponse { pub key: String, pub label: String, pub value: String, pub status: String, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct BigFishAnchorPackResponse { pub gameplay_promise: BigFishAnchorItemResponse, pub ecology_visual_theme: BigFishAnchorItemResponse, pub growth_ladder: BigFishAnchorItemResponse, pub risk_tempo: BigFishAnchorItemResponse, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishLevelBlueprintResponse { pub level: u32, pub name: String, pub one_line_fantasy: String, pub silhouette_direction: String, pub size_ratio: f32, pub visual_prompt_seed: String, pub motion_prompt_seed: String, pub merge_source_level: Option, pub prey_window: Vec, pub threat_window: Vec, pub is_final_level: bool, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct BigFishBackgroundBlueprintResponse { pub theme: String, pub color_mood: String, pub foreground_hints: String, pub midground_composition: String, pub background_depth: String, pub safe_play_area_hint: String, pub spawn_edge_hint: String, pub background_prompt_seed: String, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishRuntimeParamsResponse { pub level_count: u32, pub merge_count_per_upgrade: u32, pub spawn_target_count: u32, pub leader_move_speed: f32, pub follower_catch_up_speed: f32, pub offscreen_cull_seconds: f32, pub prey_spawn_delta_levels: Vec, pub threat_spawn_delta_levels: Vec, pub win_level: u32, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishGameDraftResponse { pub title: String, pub subtitle: String, pub core_fun: String, pub ecology_theme: String, pub levels: Vec, pub background: BigFishBackgroundBlueprintResponse, pub runtime_params: BigFishRuntimeParamsResponse, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct BigFishAgentMessageResponse { pub id: String, pub role: String, pub kind: String, pub text: String, pub created_at: String, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct BigFishAssetSlotResponse { pub slot_id: String, pub asset_kind: String, pub level: Option, pub motion_key: Option, pub status: String, pub asset_url: Option, pub prompt_snapshot: String, pub updated_at: String, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct BigFishAssetCoverageResponse { pub level_main_image_ready_count: u32, pub level_motion_ready_count: u32, pub background_ready: bool, pub required_level_count: u32, pub publish_ready: bool, pub blockers: Vec, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishSessionSnapshotResponse { pub session_id: String, pub current_turn: u32, pub progress_percent: u32, pub stage: String, pub anchor_pack: BigFishAnchorPackResponse, pub draft: Option, pub asset_slots: Vec, pub asset_coverage: BigFishAssetCoverageResponse, pub messages: Vec, pub last_assistant_reply: Option, pub publish_ready: bool, pub updated_at: String, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishSessionResponse { pub session: BigFishSessionSnapshotResponse, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishActionResponse { pub session: BigFishSessionSnapshotResponse, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishVector2Response { pub x: f32, pub y: f32, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishRuntimeEntityResponse { pub entity_id: String, pub level: u32, pub position: BigFishVector2Response, pub radius: f32, pub offscreen_seconds: f32, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishRuntimeSnapshotResponse { pub run_id: String, pub session_id: String, pub status: String, pub tick: u64, pub player_level: u32, pub win_level: u32, pub leader_entity_id: Option, pub owned_entities: Vec, pub wild_entities: Vec, pub camera_center: BigFishVector2Response, pub last_input: BigFishVector2Response, pub event_log: Vec, pub updated_at: String, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BigFishRunResponse { pub run: BigFishRuntimeSnapshotResponse, } #[cfg(test)] mod tests { use super::*; use serde_json::json; #[test] fn big_fish_session_request_uses_camel_case() { let payload = serde_json::to_value(CreateBigFishSessionRequest { seed_text: Some("深海机械鱼".to_string()), }) .expect("payload should serialize"); assert_eq!(payload, json!({ "seedText": "深海机械鱼" })); } #[test] fn big_fish_action_request_uses_camel_case() { let payload = serde_json::to_value(ExecuteBigFishActionRequest { action: "big_fish_generate_level_motion".to_string(), level: Some(3), motion_key: Some("move_swim".to_string()), }) .expect("payload should serialize"); assert_eq!(payload["motionKey"], json!("move_swim")); assert_eq!(payload["level"], json!(3)); } }