165 lines
5.9 KiB
Rust
165 lines
5.9 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct BeginStorySessionRequest {
|
|
pub runtime_session_id: String,
|
|
pub world_profile_id: String,
|
|
pub initial_prompt: String,
|
|
#[serde(default)]
|
|
pub opening_summary: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ContinueStoryRequest {
|
|
pub story_session_id: String,
|
|
pub narrative_text: String,
|
|
#[serde(default)]
|
|
pub choice_function_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct StorySessionPayload {
|
|
pub story_session_id: String,
|
|
pub runtime_session_id: String,
|
|
pub actor_user_id: String,
|
|
pub world_profile_id: String,
|
|
pub initial_prompt: String,
|
|
#[serde(default)]
|
|
pub opening_summary: Option<String>,
|
|
pub latest_narrative_text: String,
|
|
#[serde(default)]
|
|
pub latest_choice_function_id: Option<String>,
|
|
pub status: String,
|
|
pub version: u32,
|
|
pub created_at: String,
|
|
pub updated_at: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct StoryEventPayload {
|
|
pub event_id: String,
|
|
pub story_session_id: String,
|
|
pub event_kind: String,
|
|
pub narrative_text: String,
|
|
#[serde(default)]
|
|
pub choice_function_id: Option<String>,
|
|
pub created_at: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct StorySessionMutationResponse {
|
|
pub story_session: StorySessionPayload,
|
|
pub story_event: StoryEventPayload,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct StorySessionStateResponse {
|
|
pub story_session: StorySessionPayload,
|
|
pub story_events: Vec<StoryEventPayload>,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use serde_json::json;
|
|
|
|
#[test]
|
|
fn continue_story_request_uses_camel_case_fields() {
|
|
let payload = serde_json::to_value(ContinueStoryRequest {
|
|
story_session_id: "storysess_1".to_string(),
|
|
narrative_text: "继续前进".to_string(),
|
|
choice_function_id: Some("npc_chat".to_string()),
|
|
})
|
|
.expect("payload should serialize");
|
|
|
|
assert_eq!(
|
|
payload,
|
|
json!({
|
|
"storySessionId": "storysess_1",
|
|
"narrativeText": "继续前进",
|
|
"choiceFunctionId": "npc_chat"
|
|
})
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn story_session_mutation_response_uses_camel_case_fields() {
|
|
let payload = serde_json::to_value(StorySessionMutationResponse {
|
|
story_session: StorySessionPayload {
|
|
story_session_id: "storysess_1".to_string(),
|
|
runtime_session_id: "runtime_1".to_string(),
|
|
actor_user_id: "user_1".to_string(),
|
|
world_profile_id: "profile_1".to_string(),
|
|
initial_prompt: "进入营地".to_string(),
|
|
opening_summary: Some("营地开场".to_string()),
|
|
latest_narrative_text: "篝火正在燃烧。".to_string(),
|
|
latest_choice_function_id: Some("talk".to_string()),
|
|
status: "active".to_string(),
|
|
version: 1,
|
|
created_at: "1.000000Z".to_string(),
|
|
updated_at: "1.000000Z".to_string(),
|
|
},
|
|
story_event: StoryEventPayload {
|
|
event_id: "storyevt_1".to_string(),
|
|
story_session_id: "storysess_1".to_string(),
|
|
event_kind: "session_started".to_string(),
|
|
narrative_text: "篝火正在燃烧。".to_string(),
|
|
choice_function_id: Some("talk".to_string()),
|
|
created_at: "1.000000Z".to_string(),
|
|
},
|
|
})
|
|
.expect("payload should serialize");
|
|
|
|
assert_eq!(
|
|
payload["storySession"]["storySessionId"],
|
|
json!("storysess_1")
|
|
);
|
|
assert_eq!(payload["storyEvent"]["eventKind"], json!("session_started"));
|
|
assert_eq!(payload["storyEvent"]["choiceFunctionId"], json!("talk"));
|
|
}
|
|
|
|
#[test]
|
|
fn story_session_state_response_uses_camel_case_fields() {
|
|
let payload = serde_json::to_value(StorySessionStateResponse {
|
|
story_session: StorySessionPayload {
|
|
story_session_id: "storysess_1".to_string(),
|
|
runtime_session_id: "runtime_1".to_string(),
|
|
actor_user_id: "user_1".to_string(),
|
|
world_profile_id: "profile_1".to_string(),
|
|
initial_prompt: "进入营地".to_string(),
|
|
opening_summary: Some("营地开场".to_string()),
|
|
latest_narrative_text: "你看见篝火边有人招手。".to_string(),
|
|
latest_choice_function_id: Some("talk_to_npc".to_string()),
|
|
status: "active".to_string(),
|
|
version: 2,
|
|
created_at: "1.000000Z".to_string(),
|
|
updated_at: "2.000000Z".to_string(),
|
|
},
|
|
story_events: vec![StoryEventPayload {
|
|
event_id: "storyevt_2".to_string(),
|
|
story_session_id: "storysess_1".to_string(),
|
|
event_kind: "story_continued".to_string(),
|
|
narrative_text: "你看见篝火边有人招手。".to_string(),
|
|
choice_function_id: Some("talk_to_npc".to_string()),
|
|
created_at: "2.000000Z".to_string(),
|
|
}],
|
|
})
|
|
.expect("payload should serialize");
|
|
|
|
assert_eq!(
|
|
payload["storySession"]["latestChoiceFunctionId"],
|
|
json!("talk_to_npc")
|
|
);
|
|
assert_eq!(
|
|
payload["storyEvents"][0]["eventKind"],
|
|
json!("story_continued")
|
|
);
|
|
}
|
|
}
|