126 lines
3.8 KiB
Rust
126 lines
3.8 KiB
Rust
use serde::{Deserialize, Serialize};
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct StartMatch3DRunRequest {
|
||
pub profile_id: String,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct ClickMatch3DItemRequest {
|
||
#[serde(default)]
|
||
pub run_id: Option<String>,
|
||
pub item_instance_id: String,
|
||
pub client_snapshot_version: u64,
|
||
pub client_event_id: String,
|
||
pub clicked_at_ms: u64,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct StopMatch3DRunRequest {
|
||
pub client_action_id: String,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct Match3DItemSnapshotResponse {
|
||
pub item_instance_id: String,
|
||
pub item_type_id: String,
|
||
pub visual_key: String,
|
||
pub x: f32,
|
||
pub y: f32,
|
||
pub radius: f32,
|
||
pub layer: u32,
|
||
pub state: String,
|
||
pub clickable: bool,
|
||
#[serde(default)]
|
||
pub tray_slot_index: Option<u32>,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct Match3DTraySlotResponse {
|
||
pub slot_index: u32,
|
||
#[serde(default)]
|
||
pub item_instance_id: Option<String>,
|
||
#[serde(default)]
|
||
pub item_type_id: Option<String>,
|
||
#[serde(default)]
|
||
pub visual_key: Option<String>,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct Match3DRunSnapshotResponse {
|
||
pub run_id: String,
|
||
pub profile_id: String,
|
||
pub owner_user_id: String,
|
||
pub status: String,
|
||
/// 对外 HTTP 快照版本。领域层内部字段名为 board_version,facade 需要在这里完成映射。
|
||
pub snapshot_version: u64,
|
||
pub started_at_ms: u64,
|
||
pub duration_limit_ms: u64,
|
||
#[serde(default)]
|
||
pub server_now_ms: Option<u64>,
|
||
pub remaining_ms: u64,
|
||
pub clear_count: u32,
|
||
pub total_item_count: u32,
|
||
pub cleared_item_count: u32,
|
||
pub items: Vec<Match3DItemSnapshotResponse>,
|
||
pub tray_slots: Vec<Match3DTraySlotResponse>,
|
||
#[serde(default)]
|
||
pub failure_reason: Option<String>,
|
||
#[serde(default)]
|
||
pub last_confirmed_action_id: Option<String>,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct Match3DClickConfirmationResponse {
|
||
pub accepted: bool,
|
||
#[serde(default)]
|
||
pub reject_reason: Option<String>,
|
||
#[serde(default)]
|
||
pub entered_slot_index: Option<u32>,
|
||
pub cleared_item_instance_ids: Vec<String>,
|
||
pub run: Match3DRunSnapshotResponse,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct Match3DRunResponse {
|
||
pub run: Match3DRunSnapshotResponse,
|
||
}
|
||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct Match3DClickResponse {
|
||
pub confirmation: Match3DClickConfirmationResponse,
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
use serde_json::json;
|
||
|
||
#[test]
|
||
fn click_match3d_item_request_uses_camel_case() {
|
||
let payload = serde_json::to_value(ClickMatch3DItemRequest {
|
||
run_id: Some("run-1".to_string()),
|
||
item_instance_id: "item-1".to_string(),
|
||
client_snapshot_version: 7,
|
||
client_event_id: "event-1".to_string(),
|
||
clicked_at_ms: 12_345,
|
||
})
|
||
.expect("payload should serialize");
|
||
|
||
assert_eq!(payload["runId"], json!("run-1"));
|
||
assert_eq!(payload["itemInstanceId"], json!("item-1"));
|
||
assert_eq!(payload["clientSnapshotVersion"], json!(7));
|
||
assert_eq!(payload["clientEventId"], json!("event-1"));
|
||
assert_eq!(payload["clickedAtMs"], json!(12_345));
|
||
}
|
||
}
|