UI Utility

This commit is contained in:
Alex Emmet 2025-09-28 18:58:42 +00:00
commit cbd357ce14
14 changed files with 962 additions and 622 deletions

View file

@ -1,6 +1,6 @@
use axum::Json;
use json::number::Number;
use json::{JsonValue, object, parse, stringify};
use json::{Array, JsonValue, object, parse, stringify};
use std::any::Any;
use std::collections::HashMap;
use std::env::VarsOs;
@ -8,73 +8,73 @@ use std::str::FromStr;
use std::time::{SystemTime, UNIX_EPOCH};
use uuid::Uuid;
#[derive(Eq, Hash, PartialEq, Debug)]
#[derive(Eq, Hash, PartialEq, Clone, Debug)]
pub enum DataTypes {
ErrorType,
ChatPartnerId,
IotaId,
UserId,
UserIds,
UserState,
UserStates,
UserPings,
CallState,
ScreenShare,
PrivateKeyHash,
Accepted,
AcceptedProfiles,
DeniedProfiles,
MessageContent,
MessageChunk,
SendTime,
GetTime,
GetVariant,
SharedSecretOwn,
SharedSecretOther,
SharedSecretSign,
SharedSecret,
CallId,
CallName,
CallSecretSha,
CallSecret,
SharedCallSecret,
StartDate,
EndDate,
ReceiverId,
SenderId,
Signature,
Signed,
Message,
LastPing,
PingIota,
PingClients,
Matches,
Omikron,
LoadedMessages,
MessageAmount,
Position,
Name,
Path,
Codec,
Function,
Payload,
Result,
Interactables,
WantToWatch,
Watcher,
CreatedAt,
Username,
Display,
Avatar,
About,
Status,
PublicKey,
SubLevel,
SubEnd,
CommunityAddress,
Challenge,
CommunityTitle,
Communities,
error_type,
chat_partner_id,
iota_id,
user_id,
user_ids,
user_state,
user_states,
user_pings,
call_state,
screen_share,
private_key_hash,
accepted,
accepted_profiles,
denied_profiles,
message_content,
message_chunk,
send_time,
get_time,
get_variant,
shared_secret_own,
shared_secret_other,
shared_secret_sign,
shared_secret,
call_id,
call_name,
call_secret_sha,
call_secret,
shared_call_secret,
start_date,
end_date,
receiver_id,
sender_id,
signature,
signed,
message,
last_ping,
ping_iota,
ping_clients,
matches,
omikron,
loaded_messages,
message_amount,
position,
name,
path,
codec,
function,
payload,
result,
interactables,
want_to_watch,
watcher,
created_at,
username,
display,
avatar,
about,
status,
public_key,
sub_level,
sub_end,
community_address,
challenge,
community_title,
communities,
}
impl DataTypes {
@ -83,209 +83,179 @@ impl DataTypes {
let normalized = p0.to_lowercase().replace('_', "");
match normalized.as_str() {
"errortype" => DataTypes::ErrorType,
"chatpartnerid" => DataTypes::ChatPartnerId,
"iotaid" => DataTypes::IotaId,
"userid" => DataTypes::UserId,
"userids" => DataTypes::UserIds,
"userstate" => DataTypes::UserState,
"userstates" => DataTypes::UserStates,
"userpings" => DataTypes::UserPings,
"callstate" => DataTypes::CallState,
"screenshare" => DataTypes::ScreenShare,
"privatekeyhash" => DataTypes::PrivateKeyHash,
"accepted" => DataTypes::Accepted,
"acceptedprofiles" => DataTypes::AcceptedProfiles,
"deniedprofiles" => DataTypes::DeniedProfiles,
"messagecontent" => DataTypes::MessageContent,
"messagechunk" => DataTypes::MessageChunk,
"sendtime" => DataTypes::SendTime,
"gettime" => DataTypes::GetTime,
"getvariant" => DataTypes::GetVariant,
"sharedsecretown" => DataTypes::SharedSecretOwn,
"sharedsecretother" => DataTypes::SharedSecretOther,
"sharedsecretsign" => DataTypes::SharedSecretSign,
"sharedsecret" => DataTypes::SharedSecret,
"callid" => DataTypes::CallId,
"callname" => DataTypes::CallName,
"callsecretsha" => DataTypes::CallSecretSha,
"callsecret" => DataTypes::CallSecret,
"sharedcallsecret" => DataTypes::SharedCallSecret,
"startdate" => DataTypes::StartDate,
"enddate" => DataTypes::EndDate,
"receiverid" => DataTypes::ReceiverId,
"senderid" => DataTypes::SenderId,
"signature" => DataTypes::Signature,
"signed" => DataTypes::Signed,
"message" => DataTypes::Message,
"lastping" => DataTypes::LastPing,
"pingiota" => DataTypes::PingIota,
"pingclients" => DataTypes::PingClients,
"matches" => DataTypes::Matches,
"omikron" => DataTypes::Omikron,
"loadedmessages" => DataTypes::LoadedMessages,
"messageamount" => DataTypes::MessageAmount,
"position" => DataTypes::Position,
"name" => DataTypes::Name,
"path" => DataTypes::Path,
"codec" => DataTypes::Codec,
"function" => DataTypes::Function,
"payload" => DataTypes::Payload,
"result" => DataTypes::Result,
"interactables" => DataTypes::Interactables,
"wanttowatch" => DataTypes::WantToWatch,
"watcher" => DataTypes::Watcher,
"createdat" => DataTypes::CreatedAt,
"username" => DataTypes::Username,
"display" => DataTypes::Display,
"avatar" => DataTypes::Avatar,
"about" => DataTypes::About,
"status" => DataTypes::Status,
"publickey" => DataTypes::PublicKey,
"sublevel" => DataTypes::SubLevel,
"subend" => DataTypes::SubEnd,
"communityaddress" => DataTypes::CommunityAddress,
"challenge" => DataTypes::Challenge,
"communitytitle" => DataTypes::CommunityTitle,
"communities" => DataTypes::Communities,
_ => DataTypes::ErrorType, // fallback if unknown
"errortype" => DataTypes::error_type,
"chatpartnerid" => DataTypes::chat_partner_id,
"iotaid" => DataTypes::iota_id,
"userid" => DataTypes::user_id,
"userids" => DataTypes::user_ids,
"userstate" => DataTypes::user_state,
"userstates" => DataTypes::user_states,
"userpings" => DataTypes::user_pings,
"callstate" => DataTypes::call_state,
"screenshare" => DataTypes::screen_share,
"privatekeyhash" => DataTypes::private_key_hash,
"accepted" => DataTypes::accepted,
"acceptedprofiles" => DataTypes::accepted_profiles,
"deniedprofiles" => DataTypes::denied_profiles,
"messagecontent" => DataTypes::message_content,
"messagechunk" => DataTypes::message_chunk,
"sendtime" => DataTypes::send_time,
"gettime" => DataTypes::get_time,
"getvariant" => DataTypes::get_variant,
"sharedsecretown" => DataTypes::shared_secret_own,
"sharedsecretother" => DataTypes::shared_secret_other,
"sharedsecretsign" => DataTypes::shared_secret_sign,
"sharedsecret" => DataTypes::shared_secret,
"callid" => DataTypes::call_id,
"callname" => DataTypes::call_name,
"callsecretsha" => DataTypes::call_secret_sha,
"callsecret" => DataTypes::call_secret,
"sharedcallsecret" => DataTypes::shared_call_secret,
"startdate" => DataTypes::start_date,
"enddate" => DataTypes::end_date,
"receiverid" => DataTypes::receiver_id,
"senderid" => DataTypes::sender_id,
"signature" => DataTypes::signature,
"signed" => DataTypes::signed,
"message" => DataTypes::message,
"lastping" => DataTypes::last_ping,
"pingiota" => DataTypes::ping_iota,
"pingclients" => DataTypes::ping_clients,
"matches" => DataTypes::matches,
"omikron" => DataTypes::omikron,
"loadedmessages" => DataTypes::loaded_messages,
"messageamount" => DataTypes::message_amount,
"position" => DataTypes::position,
"name" => DataTypes::name,
"path" => DataTypes::path,
"codec" => DataTypes::codec,
"function" => DataTypes::function,
"payload" => DataTypes::payload,
"result" => DataTypes::result,
"interactables" => DataTypes::interactables,
"wanttowatch" => DataTypes::want_to_watch,
"watcher" => DataTypes::watcher,
"createdat" => DataTypes::created_at,
"username" => DataTypes::username,
"display" => DataTypes::display,
"avatar" => DataTypes::avatar,
"about" => DataTypes::about,
"status" => DataTypes::status,
"publickey" => DataTypes::public_key,
"sublevel" => DataTypes::sub_level,
"subend" => DataTypes::sub_end,
"communityaddress" => DataTypes::community_address,
"challenge" => DataTypes::challenge,
"communitytitle" => DataTypes::community_title,
"communities" => DataTypes::communities,
_ => DataTypes::error_type, // fallback if unknown
}
}
}
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Clone, Debug)]
pub enum CommunicationType {
Error,
Success,
Message,
MessageLive,
MessageOtherIota,
MessageChunk,
MessageGet,
ChangeConfirm,
ConfirmReceive,
ConfirmRead,
GetChats,
GetStates,
AddCommunity,
RemoveCommunity,
GetCommunities,
Challenge,
ChallengeResponse,
Register,
RegisterResponse,
Identification,
IdentificationResponse,
Ping,
Pong,
AddChat,
SendChat,
IotaConnected,
IotaClosed,
ClientChanged,
ClientConnected,
ClientClosed,
PublicKey,
PrivateKey,
WebrtcSdp,
WebrtcIce,
StartStream,
EndStream,
WatchStream,
GetCall,
NewCall,
CallInvite,
EndCall,
Function,
Update,
error,
success,
message,
message_live,
message_other_iota,
message_chunk,
message_get,
change_confirm,
confirm_receive,
confirm_read,
get_chats,
get_states,
add_community,
remove_community,
get_communities,
challenge,
challenge_response,
register,
register_response,
identification,
identification_response,
ping,
pong,
add_chat,
send_chat,
iota_connected,
iota_closed,
client_changed,
client_connected,
client_closed,
public_key,
private_key,
webrtc_sdp,
webrtc_ice,
start_stream,
end_stream,
watch_stream,
get_call,
new_call,
call_invite,
end_call,
function,
update,
}
impl CommunicationType {
pub fn parse(p0: String) -> CommunicationType {
let normalized = p0.to_lowercase().replace('_', "");
match normalized.as_str() {
"error" => CommunicationType::Error,
"success" => CommunicationType::Success,
"message" => CommunicationType::Message,
"messagelive" => CommunicationType::MessageLive,
"messageotheriota" => CommunicationType::MessageOtherIota,
"messagechunk" => CommunicationType::MessageChunk,
"messageget" => CommunicationType::MessageGet,
"changeconfirm" => CommunicationType::ChangeConfirm,
"confirmreceive" => CommunicationType::ConfirmReceive,
"confirmread" => CommunicationType::ConfirmRead,
"getchats" => CommunicationType::GetChats,
"getstates" => CommunicationType::GetStates,
"addcommunity" => CommunicationType::AddCommunity,
"removecommunity" => CommunicationType::RemoveCommunity,
"getcommunities" => CommunicationType::GetCommunities,
"challenge" => CommunicationType::Challenge,
"challengeresponse" => CommunicationType::ChallengeResponse,
"register" => CommunicationType::Register,
"registerresponse" => CommunicationType::RegisterResponse,
"identification" => CommunicationType::Identification,
"identificationresponse" => CommunicationType::IdentificationResponse,
"ping" => CommunicationType::Ping,
"pong" => CommunicationType::Pong,
"addchat" => CommunicationType::AddChat,
"sendchat" => CommunicationType::SendChat,
"iotaconnected" => CommunicationType::IotaConnected,
"iotaclosed" => CommunicationType::IotaClosed,
"clientchanged" => CommunicationType::ClientChanged,
"clientconnected" => CommunicationType::ClientConnected,
"clientclosed" => CommunicationType::ClientClosed,
"publickey" => CommunicationType::PublicKey,
"privatekey" => CommunicationType::PrivateKey,
"webrtcsdp" => CommunicationType::WebrtcSdp,
"webrtcice" => CommunicationType::WebrtcIce,
"startstream" => CommunicationType::StartStream,
"endstream" => CommunicationType::EndStream,
"watchstream" => CommunicationType::WatchStream,
"getcall" => CommunicationType::GetCall,
"newcall" => CommunicationType::NewCall,
"callinvite" => CommunicationType::CallInvite,
"endcall" => CommunicationType::EndCall,
"function" => CommunicationType::Function,
"update" => CommunicationType::Update,
_ => CommunicationType::Error, // fallback
"error" => CommunicationType::error,
"success" => CommunicationType::success,
"message" => CommunicationType::message,
"messagelive" => CommunicationType::message_live,
"messageotheriota" => CommunicationType::message_other_iota,
"messagechunk" => CommunicationType::message_chunk,
"messageget" => CommunicationType::message_get,
"changeconfirm" => CommunicationType::change_confirm,
"confirmreceive" => CommunicationType::confirm_receive,
"confirmread" => CommunicationType::confirm_read,
"getchats" => CommunicationType::get_chats,
"getstates" => CommunicationType::get_states,
"addcommunity" => CommunicationType::add_community,
"removecommunity" => CommunicationType::remove_community,
"getcommunities" => CommunicationType::get_communities,
"challenge" => CommunicationType::challenge,
"challengeresponse" => CommunicationType::challenge_response,
"register" => CommunicationType::register,
"registerresponse" => CommunicationType::register_response,
"identification" => CommunicationType::identification,
"identificationresponse" => CommunicationType::identification_response,
"ping" => CommunicationType::ping,
"pong" => CommunicationType::pong,
"addchat" => CommunicationType::add_chat,
"sendchat" => CommunicationType::send_chat,
"iotaconnected" => CommunicationType::iota_connected,
"iotaclosed" => CommunicationType::iota_closed,
"clientchanged" => CommunicationType::client_changed,
"clientconnected" => CommunicationType::client_connected,
"clientclosed" => CommunicationType::client_closed,
"publickey" => CommunicationType::public_key,
"privatekey" => CommunicationType::private_key,
"webrtcsdp" => CommunicationType::webrtc_sdp,
"webrtcice" => CommunicationType::webrtc_ice,
"startstream" => CommunicationType::start_stream,
"endstream" => CommunicationType::end_stream,
"watchstream" => CommunicationType::watch_stream,
"getcall" => CommunicationType::get_call,
"newcall" => CommunicationType::new_call,
"callinvite" => CommunicationType::call_invite,
"endcall" => CommunicationType::end_call,
"function" => CommunicationType::function,
"update" => CommunicationType::update,
_ => CommunicationType::error,
}
}
}
#[derive(Debug, Clone)]
pub enum LogLevel {
Important = 2,
Normal = 1,
Debug = 0,
None = -1,
DebugOnly = -2,
}
#[derive(Debug, Clone)]
pub struct LogValue {
pub message: String,
pub log_level: LogLevel,
}
impl LogValue {
pub fn new(message: impl Into<String>, log_level: LogLevel) -> Self {
Self {
message: message.into(),
log_level,
}
}
pub fn to_json(self) -> JsonValue {
object! {
message: self.message.clone(),
log_level: self.log_level as i32
}
}
}
#[derive(Debug)]
pub struct CommunicationValue {
pub id: Uuid,
pub comm_type: CommunicationType,
pub log_value: Option<LogValue>,
pub sender: Uuid,
pub receiver: Uuid,
pub data: HashMap<DataTypes, JsonValue>,
@ -296,7 +266,6 @@ impl CommunicationValue {
Self {
id: Uuid::new_v4(),
comm_type,
log_value: None,
sender: Uuid::new_v4(),
receiver: Uuid::new_v4(),
data: HashMap::new(),
@ -309,13 +278,6 @@ impl CommunicationValue {
pub fn get_id(&self) -> Uuid {
self.id.clone()
}
pub fn with_log(mut self, log: LogValue) -> Self {
self.log_value = Some(log);
self
}
pub fn get_log(&self) -> &Option<LogValue> {
&self.log_value
}
pub fn with_sender(mut self, sender: Uuid) -> Self {
self.sender = sender;
self
@ -342,6 +304,10 @@ impl CommunicationValue {
self.data.insert(key, value);
self
}
pub fn add_array(mut self, key: DataTypes, value: Array) -> Self {
self.data.insert(key, JsonValue::Array(value));
self
}
pub fn get_data(&mut self, key: DataTypes) -> Option<&JsonValue> {
self.data.get(&key)
}
@ -360,7 +326,6 @@ impl CommunicationValue {
type: format!("{:?}", self.comm_type),
sender: self.sender.to_string(),
receiver: self.receiver.to_string(),
log: self.log_value.as_ref().map(|l| l.clone().to_json()).unwrap_or(JsonValue::Null),
data: jdata
}
}
@ -379,14 +344,6 @@ impl CommunicationValue {
.and_then(|s| Uuid::parse_str(s).ok())
.unwrap_or(Uuid::new_v4());
let log_value = if parsed["log"].is_object() {
Some(LogValue::new(
parsed["log"]["message"].as_str().unwrap_or("").to_string(),
LogLevel::Normal,
))
} else {
None
};
let uuid = Uuid::parse_str(parsed["id"].as_str().unwrap_or("")).unwrap_or(Uuid::new_v4());
let mut data = HashMap::new();
if parsed["data"].is_object() {
@ -399,24 +356,23 @@ impl CommunicationValue {
Self {
id: uuid,
comm_type,
log_value,
sender,
receiver,
data,
}
}
pub fn ack_message(message_id: Uuid, sender: Uuid) -> CommunicationValue {
let mut cv = CommunicationValue::new(CommunicationType::Message).with_id(message_id);
let mut cv = CommunicationValue::new(CommunicationType::message).with_id(message_id);
if let s = sender {
cv = cv.add_data(DataTypes::SenderId, JsonValue::String(s.to_string()));
cv = cv.add_data(DataTypes::send_time, JsonValue::String(s.to_string()));
}
cv
}
pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue {
let receiver = Uuid::from_str(
&*original
.get_data(DataTypes::ReceiverId)
.get_data(DataTypes::receiver_id)
.unwrap()
.to_string(),
)
@ -428,15 +384,15 @@ impl CommunicationValue {
.unwrap()
.as_millis() as i64;
let cv = CommunicationValue::new(CommunicationType::MessageOtherIota)
let cv = CommunicationValue::new(CommunicationType::message_other_iota)
.with_id(original.get_id())
.with_receiver(receiver.unwrap())
.add_data(DataTypes::SendTime, JsonValue::String(now_ms.to_string()))
.add_data(DataTypes::send_time, JsonValue::String(now_ms.to_string()))
.add_data(
DataTypes::MessageContent,
DataTypes::message_content,
JsonValue::String(
original
.get_data(DataTypes::MessageContent)
.get_data(DataTypes::message_content)
.unwrap()
.to_string(),
),
@ -444,6 +400,6 @@ impl CommunicationValue {
// include sender_id if the original had one
let sender = original.get_sender();
cv.add_data(DataTypes::SenderId, JsonValue::String(sender.to_string()))
cv.add_data(DataTypes::sender_id, JsonValue::String(sender.to_string()))
}
}