refactor: split large modules and normalize rust layout
This commit is contained in:
440
server-rs/crates/spacetime-client/src/mapper/runtime.rs
Normal file
440
server-rs/crates/spacetime-client/src/mapper/runtime.rs
Normal file
@@ -0,0 +1,440 @@
|
||||
use super::*;
|
||||
|
||||
impl From<module_runtime::CreationEntryTypeAdminUpsertInput> for CreationEntryTypeAdminUpsertInput {
|
||||
fn from(input: module_runtime::CreationEntryTypeAdminUpsertInput) -> Self {
|
||||
Self {
|
||||
id: input.id,
|
||||
title: input.title,
|
||||
subtitle: input.subtitle,
|
||||
badge: input.badge,
|
||||
image_src: input.image_src,
|
||||
visible: input.visible,
|
||||
open: input.open,
|
||||
sort_order: input.sort_order,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeSettingGetInput> for RuntimeSettingGetInput {
|
||||
fn from(input: module_runtime::RuntimeSettingGetInput) -> Self {
|
||||
Self {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeSettingUpsertInput> for RuntimeSettingUpsertInput {
|
||||
fn from(input: module_runtime::RuntimeSettingUpsertInput) -> Self {
|
||||
Self {
|
||||
user_id: input.user_id,
|
||||
music_volume: input.music_volume,
|
||||
platform_theme: map_runtime_platform_theme(input.platform_theme),
|
||||
updated_at_micros: input.updated_at_micros,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeBrowseHistoryListInput> for RuntimeBrowseHistoryListInput {
|
||||
fn from(input: module_runtime::RuntimeBrowseHistoryListInput) -> Self {
|
||||
Self {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeBrowseHistoryClearInput> for RuntimeBrowseHistoryClearInput {
|
||||
fn from(input: module_runtime::RuntimeBrowseHistoryClearInput) -> Self {
|
||||
Self {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeBrowseHistorySyncInput> for RuntimeBrowseHistorySyncInput {
|
||||
fn from(input: module_runtime::RuntimeBrowseHistorySyncInput) -> Self {
|
||||
Self {
|
||||
user_id: input.user_id,
|
||||
entries: input.entries.into_iter().map(Into::into).collect(),
|
||||
updated_at_micros: input.updated_at_micros,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeBrowseHistoryWriteInput> for RuntimeBrowseHistoryWriteInput {
|
||||
fn from(input: module_runtime::RuntimeBrowseHistoryWriteInput) -> Self {
|
||||
Self {
|
||||
owner_user_id: input.owner_user_id,
|
||||
profile_id: input.profile_id,
|
||||
world_name: input.world_name,
|
||||
subtitle: input.subtitle,
|
||||
summary_text: input.summary_text,
|
||||
cover_image_src: input.cover_image_src,
|
||||
theme_mode: input.theme_mode,
|
||||
author_display_name: input.author_display_name,
|
||||
visited_at: input.visited_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeSnapshotGetInput> for RuntimeSnapshotGetInput {
|
||||
fn from(input: module_runtime::RuntimeSnapshotGetInput) -> Self {
|
||||
Self {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeSnapshotDeleteInput> for RuntimeSnapshotDeleteInput {
|
||||
fn from(input: module_runtime::RuntimeSnapshotDeleteInput) -> Self {
|
||||
Self {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type CreationEntryConfigRecord =
|
||||
shared_contracts::creation_entry_config::CreationEntryConfigResponse;
|
||||
|
||||
pub(crate) fn map_creation_entry_config_procedure_result(
|
||||
result: CreationEntryConfigProcedureResult,
|
||||
) -> Result<CreationEntryConfigRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
|
||||
let snapshot = result
|
||||
.record
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("创作入口配置快照"))?;
|
||||
|
||||
Ok(module_runtime::build_creation_entry_config_response(
|
||||
map_creation_entry_config_snapshot(snapshot),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn build_creation_entry_config_record_from_rows(
|
||||
header: CreationEntryConfig,
|
||||
mut creation_types: Vec<CreationEntryTypeConfig>,
|
||||
) -> CreationEntryConfigRecord {
|
||||
creation_types.sort_by(|left, right| {
|
||||
left.sort_order
|
||||
.cmp(&right.sort_order)
|
||||
.then_with(|| left.id.cmp(&right.id))
|
||||
});
|
||||
|
||||
module_runtime::build_creation_entry_config_response(
|
||||
module_runtime::CreationEntryConfigSnapshot {
|
||||
config_id: header.config_id,
|
||||
start_card: module_runtime::CreationEntryStartCardSnapshot {
|
||||
title: header.start_title,
|
||||
description: header.start_description,
|
||||
idle_badge: header.start_idle_badge,
|
||||
busy_badge: header.start_busy_badge,
|
||||
},
|
||||
type_modal: module_runtime::CreationEntryTypeModalSnapshot {
|
||||
title: header.modal_title,
|
||||
description: header.modal_description,
|
||||
},
|
||||
creation_types: creation_types
|
||||
.into_iter()
|
||||
.map(|item| module_runtime::CreationEntryTypeSnapshot {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
subtitle: item.subtitle,
|
||||
badge: item.badge,
|
||||
image_src: item.image_src,
|
||||
visible: item.visible,
|
||||
open: item.open,
|
||||
sort_order: item.sort_order,
|
||||
updated_at_micros: item.updated_at.to_micros_since_unix_epoch(),
|
||||
})
|
||||
.collect(),
|
||||
updated_at_micros: header.updated_at.to_micros_since_unix_epoch(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn map_creation_entry_config_snapshot(
|
||||
snapshot: CreationEntryConfigSnapshot,
|
||||
) -> module_runtime::CreationEntryConfigSnapshot {
|
||||
module_runtime::CreationEntryConfigSnapshot {
|
||||
config_id: snapshot.config_id,
|
||||
start_card: module_runtime::CreationEntryStartCardSnapshot {
|
||||
title: snapshot.start_card.title,
|
||||
description: snapshot.start_card.description,
|
||||
idle_badge: snapshot.start_card.idle_badge,
|
||||
busy_badge: snapshot.start_card.busy_badge,
|
||||
},
|
||||
type_modal: module_runtime::CreationEntryTypeModalSnapshot {
|
||||
title: snapshot.type_modal.title,
|
||||
description: snapshot.type_modal.description,
|
||||
},
|
||||
creation_types: snapshot
|
||||
.creation_types
|
||||
.into_iter()
|
||||
.map(|item| module_runtime::CreationEntryTypeSnapshot {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
subtitle: item.subtitle,
|
||||
badge: item.badge,
|
||||
image_src: item.image_src,
|
||||
visible: item.visible,
|
||||
open: item.open,
|
||||
sort_order: item.sort_order,
|
||||
updated_at_micros: item.updated_at_micros,
|
||||
})
|
||||
.collect(),
|
||||
updated_at_micros: snapshot.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_setting_procedure_result(
|
||||
result: RuntimeSettingProcedureResult,
|
||||
) -> Result<RuntimeSettingsRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
|
||||
let snapshot = result
|
||||
.record
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("runtime settings 快照"))?;
|
||||
|
||||
Ok(build_runtime_setting_record(map_runtime_setting_snapshot(
|
||||
snapshot,
|
||||
)))
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_tracking_event_procedure_result(
|
||||
result: RuntimeTrackingEventProcedureResult,
|
||||
) -> Result<(), SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_snapshot_procedure_result(
|
||||
result: RuntimeSnapshotProcedureResult,
|
||||
) -> Result<Option<RuntimeSnapshotRecord>, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
|
||||
result
|
||||
.record
|
||||
.map(|snapshot| {
|
||||
build_runtime_snapshot_record(map_runtime_snapshot_snapshot(snapshot))
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_snapshot_required_procedure_result(
|
||||
result: RuntimeSnapshotProcedureResult,
|
||||
) -> Result<RuntimeSnapshotRecord, SpacetimeClientError> {
|
||||
map_runtime_snapshot_procedure_result(result)?
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("runtime snapshot 快照"))
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_snapshot_delete_procedure_result(
|
||||
result: RuntimeSnapshotProcedureResult,
|
||||
) -> Result<bool, SpacetimeClientError> {
|
||||
map_runtime_snapshot_procedure_result(result).map(|record| record.is_some())
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_setting_snapshot(
|
||||
snapshot: RuntimeSettingSnapshot,
|
||||
) -> module_runtime::RuntimeSettingSnapshot {
|
||||
module_runtime::RuntimeSettingSnapshot {
|
||||
user_id: snapshot.user_id,
|
||||
music_volume: snapshot.music_volume,
|
||||
platform_theme: map_runtime_platform_theme_back(snapshot.platform_theme),
|
||||
created_at_micros: snapshot.created_at_micros,
|
||||
updated_at_micros: snapshot.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_platform_theme(
|
||||
value: DomainRuntimePlatformTheme,
|
||||
) -> crate::module_bindings::RuntimePlatformTheme {
|
||||
match value {
|
||||
DomainRuntimePlatformTheme::Light => crate::module_bindings::RuntimePlatformTheme::Light,
|
||||
DomainRuntimePlatformTheme::Dark => crate::module_bindings::RuntimePlatformTheme::Dark,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_platform_theme_back(
|
||||
value: crate::module_bindings::RuntimePlatformTheme,
|
||||
) -> DomainRuntimePlatformTheme {
|
||||
match value {
|
||||
crate::module_bindings::RuntimePlatformTheme::Light => DomainRuntimePlatformTheme::Light,
|
||||
crate::module_bindings::RuntimePlatformTheme::Dark => DomainRuntimePlatformTheme::Dark,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_tracking_scope_kind(
|
||||
value: DomainRuntimeTrackingScopeKind,
|
||||
) -> crate::module_bindings::RuntimeTrackingScopeKind {
|
||||
match value {
|
||||
DomainRuntimeTrackingScopeKind::Site => {
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::Site
|
||||
}
|
||||
DomainRuntimeTrackingScopeKind::Work => {
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::Work
|
||||
}
|
||||
DomainRuntimeTrackingScopeKind::Module => {
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::Module
|
||||
}
|
||||
DomainRuntimeTrackingScopeKind::User => {
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::User
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_tracking_scope_kind_back(
|
||||
value: crate::module_bindings::RuntimeTrackingScopeKind,
|
||||
) -> DomainRuntimeTrackingScopeKind {
|
||||
match value {
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::Site => {
|
||||
DomainRuntimeTrackingScopeKind::Site
|
||||
}
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::Work => {
|
||||
DomainRuntimeTrackingScopeKind::Work
|
||||
}
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::Module => {
|
||||
DomainRuntimeTrackingScopeKind::Module
|
||||
}
|
||||
crate::module_bindings::RuntimeTrackingScopeKind::User => {
|
||||
DomainRuntimeTrackingScopeKind::User
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_json_value(
|
||||
value: &str,
|
||||
label: &str,
|
||||
) -> Result<serde_json::Value, SpacetimeClientError> {
|
||||
serde_json::from_str::<serde_json::Value>(value)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(format!("{label} 非法: {error}")))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_json_array(
|
||||
value: &str,
|
||||
label: &str,
|
||||
) -> Result<Vec<serde_json::Value>, SpacetimeClientError> {
|
||||
match parse_json_value(value, label)? {
|
||||
serde_json::Value::Array(entries) => Ok(entries),
|
||||
_ => Err(SpacetimeClientError::Runtime(format!(
|
||||
"{label} 必须是 JSON array"
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_json_string_array(
|
||||
value: &str,
|
||||
label: &str,
|
||||
) -> Result<Vec<String>, SpacetimeClientError> {
|
||||
parse_json_array(value, label)?
|
||||
.into_iter()
|
||||
.map(|entry| match entry {
|
||||
serde_json::Value::String(value) => Ok(value),
|
||||
_ => Err(SpacetimeClientError::Runtime(format!(
|
||||
"{label} 必须是 string array"
|
||||
))),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn parse_supported_actions_json(
|
||||
value: &str,
|
||||
) -> Result<Vec<CustomWorldSupportedActionRecord>, SpacetimeClientError> {
|
||||
parse_json_array(value, "custom world agent supported_actions_json")?
|
||||
.into_iter()
|
||||
.map(|entry| {
|
||||
let object = entry.as_object().ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world supported action 必须是 JSON object".to_string(),
|
||||
)
|
||||
})?;
|
||||
let action = object
|
||||
.get("action")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world supported action.action 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
let enabled = object
|
||||
.get("enabled")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world supported action.enabled 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(CustomWorldSupportedActionRecord {
|
||||
action: action.to_string(),
|
||||
enabled,
|
||||
reason: object
|
||||
.get("reason")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(ToOwned::to_owned),
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct BigFishRuntimeParamsRecord {
|
||||
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<u32>,
|
||||
pub threat_spawn_delta_levels: Vec<u32>,
|
||||
pub win_level: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct BigFishGameDraftRecord {
|
||||
pub title: String,
|
||||
pub subtitle: String,
|
||||
pub core_fun: String,
|
||||
pub ecology_theme: String,
|
||||
pub levels: Vec<BigFishLevelBlueprintRecord>,
|
||||
pub background: BigFishBackgroundBlueprintRecord,
|
||||
pub runtime_params: BigFishRuntimeParamsRecord,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct BigFishRuntimeEntityRecord {
|
||||
pub entity_id: String,
|
||||
pub level: u32,
|
||||
pub position: BigFishVector2Record,
|
||||
pub radius: f32,
|
||||
pub offscreen_seconds: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct BigFishRuntimeRunRecord {
|
||||
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<String>,
|
||||
pub owned_entities: Vec<BigFishRuntimeEntityRecord>,
|
||||
pub wild_entities: Vec<BigFishRuntimeEntityRecord>,
|
||||
pub camera_center: BigFishVector2Record,
|
||||
pub last_input: BigFishVector2Record,
|
||||
pub event_log: Vec<String>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
Reference in New Issue
Block a user