Files
Genarrative/server-rs/crates/shared-contracts/src/creation_audio.rs
2026-05-11 20:27:41 +08:00

129 lines
4.0 KiB
Rust

use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CreationAudioGenerationKind {
BackgroundMusic,
SoundEffect,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct CreationAudioAsset {
pub task_id: String,
pub provider: String,
#[serde(default)]
pub asset_object_id: Option<String>,
#[serde(default)]
pub asset_kind: Option<String>,
pub audio_src: String,
#[serde(default)]
pub prompt: Option<String>,
#[serde(default)]
pub title: Option<String>,
#[serde(default)]
pub updated_at: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct CreateBackgroundMusicRequest {
pub prompt: String,
pub title: String,
#[serde(default)]
pub tags: Option<String>,
#[serde(default)]
pub model: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct CreateSoundEffectRequest {
pub prompt: String,
#[serde(default)]
pub duration: Option<u8>,
#[serde(default)]
pub seed: Option<u64>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AudioGenerationTaskResponse {
pub kind: CreationAudioGenerationKind,
pub task_id: String,
pub provider: String,
pub status: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CreationAudioStoragePrefix {
PuzzleAssets,
#[serde(rename = "match3d_assets")]
Match3DAssets,
CustomWorldScenes,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct PublishGeneratedAudioAssetRequest {
pub entity_kind: String,
pub entity_id: String,
pub slot: String,
pub asset_kind: String,
#[serde(default)]
pub profile_id: Option<String>,
#[serde(default)]
pub storage_prefix: Option<CreationAudioStoragePrefix>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct GeneratedAudioAssetResponse {
pub kind: CreationAudioGenerationKind,
pub task_id: String,
pub provider: String,
pub status: String,
#[serde(default)]
pub asset_object_id: Option<String>,
#[serde(default)]
pub asset_kind: Option<String>,
#[serde(default)]
pub audio_src: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn creation_audio_contracts_use_camel_case_fields() {
let request = PublishGeneratedAudioAssetRequest {
entity_kind: "match3d_item".to_string(),
entity_id: "match3d-item-1".to_string(),
slot: "click_sound".to_string(),
asset_kind: "match3d_click_sound".to_string(),
profile_id: Some("profile-1".to_string()),
storage_prefix: Some(CreationAudioStoragePrefix::Match3DAssets),
};
let payload = serde_json::to_value(request).expect("request should serialize");
assert_eq!(payload["entityKind"], json!("match3d_item"));
assert_eq!(payload["storagePrefix"], json!("match3d_assets"));
let asset = CreationAudioAsset {
task_id: "task-1".to_string(),
provider: "vector-engine-suno".to_string(),
asset_object_id: Some("assetobj_1".to_string()),
asset_kind: Some("puzzle_background_music".to_string()),
audio_src: "/generated-puzzle-assets/a.mp3".to_string(),
prompt: Some("轻快音乐".to_string()),
title: Some("拼图音乐".to_string()),
updated_at: Some("2026-05-11T00:00:00Z".to_string()),
};
let payload = serde_json::to_value(asset).expect("asset should serialize");
assert_eq!(payload["taskId"], json!("task-1"));
assert_eq!(payload["audioSrc"], json!("/generated-puzzle-assets/a.mp3"));
}
}