#![allow(dead_code)]
#![allow(non_snake_case)]
use newtype::NewType;
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ConfigRelayDetail {
relayIdleTime: u64,
downloadIdleTime: u64,
relayProtectTime: u64,
downloadProtectTime: u64,
}
#[allow(non_snake_case)]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ConfigRelay {
pub relayGroup: ConfigRelayDetail,
pub relayGroupManager: ConfigRelayDetail,
}
impl ConfigRelayDetail {
pub fn relayIdleTime(&self) -> Duration {
Duration::from_millis(self.relayIdleTime)
}
pub fn downloadIdleTime(&self) -> Duration {
Duration::from_millis(self.downloadIdleTime)
}
pub fn relayProtectTime(&self) -> Duration {
Duration::from_millis(self.relayProtectTime)
}
pub fn downloadProtectTime(&self) -> Duration {
Duration::from_millis(self.downloadProtectTime)
}
}
#[derive(Deserialize, Debug, Clone)]
pub struct ConfigApi {
ip: Option<String>,
port: Option<u32>,
}
impl ConfigApi {
pub fn ip(&self) -> &Option<String> {
&self.ip
}
pub fn port(&self) -> &Option<u32> {
&self.port
}
}
#[derive(Clone, Debug, serde::Deserialize, NewType, PartialEq, Eq)]
pub struct RealHandle(String);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MediaGlobalIndex {
access_id: String,
relay_group_id: String,
relay_id: Option<String>,
}
impl MediaGlobalIndex {
pub fn new(access_id: impl Into<String>, relay_group_id: impl Into<String>, relay_id: Option<&str>) -> Self {
Self {
access_id: access_id.into(),
relay_group_id: relay_group_id.into(),
relay_id: relay_id.map(|id| id.into()),
}
}
pub fn access_id(&self) -> &str {
&self.access_id
}
pub fn relay_group_id(&self) -> &str {
&self.relay_group_id
}
pub fn relay_id(&self) -> &Option<String> {
&self.relay_id
}
}
impl TryFrom<RealHandle> for MediaGlobalIndex {
type Error = anyhow::Error;
fn try_from(value: RealHandle) -> Result<Self, Self::Error> {
let parts: Vec<&str> = value.0.split('-').collect();
let access_id = parts
.get(0)
.ok_or_else(|| anyhow::anyhow!("Invalid RealHandle format"))?
.to_string();
let relay_group_id = parts
.get(1)
.ok_or_else(|| anyhow::anyhow!("Invalid RealHandle format"))?
.to_string();
let relay_id = parts.get(2).map(|s| s.to_string());
Ok(Self {
access_id,
relay_group_id,
relay_id,
})
}
}
#[derive(Clone, Debug, serde::Deserialize, PartialEq, Eq)]
pub struct RealResultOk {
handle: RealHandle,
#[serde(default)]
isFirstAccess: bool,
url: String,
}
impl RealResultOk {
pub fn new(handle: impl Into<String>, isFirstAccess: bool, url: impl Into<String>) -> Self {
Self {
handle: handle.into().into(),
isFirstAccess,
url: url.into(),
}
}
pub fn handle(&self) -> &RealHandle {
&self.handle
}
pub fn is_first_access(&self) -> bool {
self.isFirstAccess
}
pub fn url(&self) -> &str {
&self.url
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_case_real_result() {
let json_str = r#"
{
"handle": "2756985974-3446087304",
"isFirstAccess": true,
"url": "http://127.0.0.1:5543/3446087304/aab8c5d1-7251-4371-b4ba-3923e7be894a.live.ts"
}
"#;
let real_result = serde_json::from_str::<RealResultOk>(json_str).unwrap();
assert_eq!(
real_result.handle().to_owned(),
RealHandle::from("2756985974-3446087304".to_string())
);
assert_eq!(real_result.is_first_access(), true);
assert_eq!(
real_result.url(),
"http://127.0.0.1:5543/3446087304/aab8c5d1-7251-4371-b4ba-3923e7be894a.live.ts"
);
assert_eq!(
real_result,
RealResultOk::new(
"2756985974-3446087304",
true,
"http://127.0.0.1:5543/3446087304/aab8c5d1-7251-4371-b4ba-3923e7be894a.live.ts"
)
);
}
#[test]
fn test_media_global_index() {
{
let handle = RealHandle::from("2756985974-3446087304-1".to_string());
let media_global_index = MediaGlobalIndex::try_from(handle).unwrap();
assert_eq!(
media_global_index,
MediaGlobalIndex::new("2756985974", "3446087304", Some("1"))
);
}
{
let handle = RealHandle::from("2756985974-3446087304".to_string());
let media_global_index = MediaGlobalIndex::try_from(handle).unwrap();
assert_eq!(
media_global_index,
MediaGlobalIndex::new("2756985974", "3446087304", None)
);
}
}
}