1
This commit is contained in:
169
server-rs/crates/shared-contracts/src/hyper3d.rs
Normal file
169
server-rs/crates/shared-contracts/src/hyper3d.rs
Normal file
@@ -0,0 +1,169 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum Hyper3dGenerationMode {
|
||||
TextToModel,
|
||||
ImageToModel,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dTextToModelRequest {
|
||||
pub prompt: String,
|
||||
#[serde(default)]
|
||||
pub negative_prompt: Option<String>,
|
||||
#[serde(default)]
|
||||
pub seed: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub geometry_file_format: Option<String>,
|
||||
#[serde(default)]
|
||||
pub material: Option<String>,
|
||||
#[serde(default)]
|
||||
pub quality: Option<String>,
|
||||
#[serde(default)]
|
||||
pub mesh_mode: Option<String>,
|
||||
#[serde(default)]
|
||||
pub addons: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub bbox_condition: Option<Vec<f32>>,
|
||||
#[serde(default)]
|
||||
pub preview_render: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dImageToModelRequest {
|
||||
#[serde(default)]
|
||||
pub image_data_urls: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub image_urls: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub prompt: Option<String>,
|
||||
#[serde(default)]
|
||||
pub condition_mode: Option<String>,
|
||||
#[serde(default)]
|
||||
pub seed: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub geometry_file_format: Option<String>,
|
||||
#[serde(default)]
|
||||
pub material: Option<String>,
|
||||
#[serde(default)]
|
||||
pub quality: Option<String>,
|
||||
#[serde(default)]
|
||||
pub mesh_mode: Option<String>,
|
||||
#[serde(default)]
|
||||
pub addons: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub bbox_condition: Option<Vec<f32>>,
|
||||
#[serde(default)]
|
||||
pub preview_render: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dTaskSubmitResponse {
|
||||
pub ok: bool,
|
||||
pub provider: String,
|
||||
pub mode: Hyper3dGenerationMode,
|
||||
pub task_uuid: String,
|
||||
pub subscription_key: String,
|
||||
pub job_uuids: Vec<String>,
|
||||
pub message: Option<String>,
|
||||
pub tier: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dTaskStatusRequest {
|
||||
pub subscription_key: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dTaskStatusResponse {
|
||||
pub ok: bool,
|
||||
pub provider: String,
|
||||
pub status: String,
|
||||
#[serde(default)]
|
||||
pub jobs: Vec<Hyper3dJobStatusPayload>,
|
||||
pub raw: Value,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dJobStatusPayload {
|
||||
pub uuid: Option<String>,
|
||||
pub status: String,
|
||||
pub progress: Option<f32>,
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dDownloadRequest {
|
||||
pub task_uuid: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dDownloadResponse {
|
||||
pub ok: bool,
|
||||
pub provider: String,
|
||||
#[serde(default)]
|
||||
pub files: Vec<Hyper3dDownloadFilePayload>,
|
||||
pub raw: Value,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyper3dDownloadFilePayload {
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn text_to_model_request_uses_camel_case_fields() {
|
||||
let payload = serde_json::to_value(Hyper3dTextToModelRequest {
|
||||
prompt: "低多边形宝箱".to_string(),
|
||||
negative_prompt: Some("文字".to_string()),
|
||||
seed: Some(42),
|
||||
geometry_file_format: Some("glb".to_string()),
|
||||
material: Some("PBR".to_string()),
|
||||
quality: Some("medium".to_string()),
|
||||
mesh_mode: Some("Quad".to_string()),
|
||||
addons: vec!["HighPack".to_string()],
|
||||
bbox_condition: Some(vec![1.0, 1.0, 1.0]),
|
||||
preview_render: Some(true),
|
||||
})
|
||||
.expect("request should serialize");
|
||||
|
||||
assert_eq!(payload["geometryFileFormat"], json!("glb"));
|
||||
assert_eq!(payload["meshMode"], json!("Quad"));
|
||||
assert_eq!(payload["bboxCondition"], json!([1.0, 1.0, 1.0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn submit_response_keeps_mode_as_kebab_case() {
|
||||
let payload = serde_json::to_value(Hyper3dTaskSubmitResponse {
|
||||
ok: true,
|
||||
provider: "hyper3d-rodin".to_string(),
|
||||
mode: Hyper3dGenerationMode::ImageToModel,
|
||||
task_uuid: "task-1".to_string(),
|
||||
subscription_key: "sub-1".to_string(),
|
||||
job_uuids: vec!["job-1".to_string()],
|
||||
message: Some("submitted".to_string()),
|
||||
tier: "Gen-2".to_string(),
|
||||
})
|
||||
.expect("response should serialize");
|
||||
|
||||
assert_eq!(payload["mode"], json!("image-to-model"));
|
||||
assert_eq!(payload["subscriptionKey"], json!("sub-1"));
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ pub mod big_fish;
|
||||
pub mod big_fish_works;
|
||||
pub mod creation_agent_document_input;
|
||||
pub mod creative_agent;
|
||||
pub mod hyper3d;
|
||||
pub mod llm;
|
||||
pub mod match3d_agent;
|
||||
pub mod match3d_runtime;
|
||||
|
||||
Reference in New Issue
Block a user