use crate::lxapp::ReleaseType;
use lingxia_platform::traits::app_runtime::LxAppPresentation;
use serde::{Deserialize, Serialize, Serializer, ser::SerializeMap};
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Default)]
pub enum Scene {
#[default]
System = 8000,
NavigateTo = 8001,
NavigateBack = 8002,
AppLink = 8003,
}
impl From<i32> for Scene {
fn from(n: i32) -> Self {
match n {
8000 => Scene::System,
8001 => Scene::NavigateTo,
8002 => Scene::NavigateBack,
8003 => Scene::AppLink,
_ => Scene::System,
}
}
}
#[derive(Deserialize, Debug, Default, Clone)]
pub struct LxAppStartupOptions {
pub path: String,
pub query: String,
pub release_type: ReleaseType,
pub scene: Scene,
#[serde(skip)]
pub presentation: LxAppPresentation,
#[serde(skip)]
pub panel_id: String,
}
impl serde::Serialize for LxAppStartupOptions {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(None)?;
map.serialize_entry("path", &self.path)?;
map.serialize_entry("scene", &(self.scene as u32))?;
if let Ok(query_value) = parse_query_string(&self.query)
&& let Some(query_map) = query_value.as_object()
{
for (k, v) in query_map {
map.serialize_entry(k, v)?;
}
}
map.end()
}
}
pub fn parse_query_string(query_str: &str) -> Result<serde_json::Value, serde_json::Error> {
if query_str.is_empty() {
return Ok(serde_json::Value::Null);
}
let mut query_map = serde_json::Map::new();
for pair in query_str.split('&') {
if let Some(eq_pos) = pair.find('=') {
let key = &pair[..eq_pos];
let value = &pair[eq_pos + 1..];
let decoded_value =
urlencoding::decode(value).unwrap_or(std::borrow::Cow::Borrowed(value));
query_map.insert(
key.to_string(),
serde_json::Value::String(decoded_value.to_string()),
);
} else {
query_map.insert(pair.to_string(), serde_json::Value::String("".to_string()));
}
}
Ok(serde_json::Value::Object(query_map))
}
pub fn split_path_query(url: &str) -> (String, Option<String>) {
if let Some(idx) = url.find('?') {
let (path, query) = url.split_at(idx);
(path.to_string(), Some(query[1..].to_string()))
} else {
(url.to_string(), None)
}
}
pub fn parse_env_release_type(tag: &str) -> ReleaseType {
match tag {
"develop" => ReleaseType::Developer,
"trial" => ReleaseType::Preview,
_ => ReleaseType::Release,
}
}
impl LxAppStartupOptions {
pub fn new(path_with_query: &str) -> Self {
let (path, query_str) = if let Some(idx) = path_with_query.find('?') {
let (p, q) = path_with_query.split_at(idx);
(p, &q[1..])
} else {
(path_with_query, "")
};
Self {
path: path.to_string(),
query: query_str.to_string(),
release_type: ReleaseType::Release,
presentation: LxAppPresentation::Normal,
panel_id: String::new(),
..Default::default()
}
}
pub fn set_release_type(mut self, release_type: ReleaseType) -> Self {
self.release_type = release_type;
self
}
pub fn set_scene(mut self, scene: Scene) -> Self {
self.scene = scene;
self
}
pub fn set_query(mut self, query: String) -> Self {
self.query = query;
self
}
pub fn set_presentation(mut self, presentation: LxAppPresentation) -> Self {
self.presentation = presentation;
self
}
pub fn set_panel_id(mut self, panel_id: String) -> Self {
self.panel_id = panel_id;
self
}
}