Add: windows mvp - transparent bugs not fixed
This commit is contained in:
173
crates/sprimo-protocol/src/lib.rs
Normal file
173
crates/sprimo-protocol/src/lib.rs
Normal file
@@ -0,0 +1,173 @@
|
||||
pub mod v1 {
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FrontendState {
|
||||
Idle,
|
||||
Active,
|
||||
Success,
|
||||
Error,
|
||||
Dragging,
|
||||
Hidden,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct AnimationPriority(pub u8);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct CommandEnvelope {
|
||||
pub id: Uuid,
|
||||
pub ts_ms: i64,
|
||||
pub command: FrontendCommand,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", content = "payload", rename_all = "snake_case")]
|
||||
pub enum FrontendCommand {
|
||||
SetState {
|
||||
state: FrontendState,
|
||||
ttl_ms: Option<u64>,
|
||||
},
|
||||
PlayAnimation {
|
||||
name: String,
|
||||
priority: AnimationPriority,
|
||||
duration_ms: Option<u64>,
|
||||
interrupt: Option<bool>,
|
||||
},
|
||||
SetSpritePack {
|
||||
pack_id_or_path: String,
|
||||
},
|
||||
SetTransform {
|
||||
x: Option<f32>,
|
||||
y: Option<f32>,
|
||||
anchor: Option<String>,
|
||||
scale: Option<f32>,
|
||||
opacity: Option<f32>,
|
||||
},
|
||||
SetFlags {
|
||||
click_through: Option<bool>,
|
||||
always_on_top: Option<bool>,
|
||||
visible: Option<bool>,
|
||||
},
|
||||
Toast {
|
||||
text: String,
|
||||
ttl_ms: Option<u64>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct CapabilityFlags {
|
||||
pub supports_click_through: bool,
|
||||
pub supports_transparency: bool,
|
||||
pub supports_tray: bool,
|
||||
pub supports_global_hotkey: bool,
|
||||
pub supports_skip_taskbar: bool,
|
||||
}
|
||||
|
||||
impl Default for CapabilityFlags {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
supports_click_through: false,
|
||||
supports_transparency: true,
|
||||
supports_tray: false,
|
||||
supports_global_hotkey: false,
|
||||
supports_skip_taskbar: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct OverlayFlags {
|
||||
pub click_through: bool,
|
||||
pub always_on_top: bool,
|
||||
pub visible: bool,
|
||||
}
|
||||
|
||||
impl Default for OverlayFlags {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
click_through: false,
|
||||
always_on_top: true,
|
||||
visible: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct FrontendStateSnapshot {
|
||||
pub state: FrontendState,
|
||||
pub current_animation: String,
|
||||
pub flags: OverlayFlags,
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub scale: f32,
|
||||
pub active_sprite_pack: String,
|
||||
pub capabilities: CapabilityFlags,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub last_error: Option<String>,
|
||||
}
|
||||
|
||||
impl FrontendStateSnapshot {
|
||||
#[must_use]
|
||||
pub fn idle(capabilities: CapabilityFlags) -> Self {
|
||||
Self {
|
||||
state: FrontendState::Idle,
|
||||
current_animation: "idle".to_string(),
|
||||
flags: OverlayFlags::default(),
|
||||
x: 200.0,
|
||||
y: 200.0,
|
||||
scale: 1.0,
|
||||
active_sprite_pack: "default".to_string(),
|
||||
capabilities,
|
||||
last_error: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct HealthResponse {
|
||||
pub version: String,
|
||||
pub build: String,
|
||||
pub uptime_seconds: u64,
|
||||
pub active_sprite_pack: String,
|
||||
pub capabilities: CapabilityFlags,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ErrorResponse {
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::v1::{AnimationPriority, CommandEnvelope, FrontendCommand, FrontendState};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[test]
|
||||
fn command_envelope_roundtrip() {
|
||||
let payload = CommandEnvelope {
|
||||
id: Uuid::nil(),
|
||||
ts_ms: 1_737_000_000_000,
|
||||
command: FrontendCommand::PlayAnimation {
|
||||
name: "dance".to_string(),
|
||||
priority: AnimationPriority(9),
|
||||
duration_ms: Some(1_200),
|
||||
interrupt: Some(true),
|
||||
},
|
||||
};
|
||||
|
||||
let encoded = serde_json::to_string(&payload).expect("serialize");
|
||||
let decoded: CommandEnvelope = serde_json::from_str(&encoded).expect("deserialize");
|
||||
assert_eq!(decoded, payload);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn state_serializes_as_snake_case() {
|
||||
let encoded = serde_json::to_string(&FrontendState::Hidden).expect("serialize");
|
||||
assert_eq!(encoded, "\"hidden\"");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user