use std::collections::HashMap;
use ani_rs::objects::AniObject;
use request_core::config::{self, CommonTaskConfig, NetworkConfig, TaskConfig, Version};
use request_core::info;
use serde::{Deserialize, Serialize};
#[derive(Clone)]
#[ani_rs::ani(path = "@ohos.request.request.agent.Action")]
pub enum Action {
Download,
Upload,
}
impl From<Action> for request_core::config::Action {
fn from(value: Action) -> Self {
match value {
Action::Download => config::Action::Download,
Action::Upload => config::Action::Upload,
}
}
}
impl From<config::Action> for Action {
fn from(value: config::Action) -> Self {
match value {
config::Action::Download => Action::Download,
config::Action::Upload => Action::Upload,
}
}
}
impl From<u8> for Action {
fn from(value: u8) -> Self {
match value {
0 => Action::Download,
1 => Action::Upload,
_ => unimplemented!(),
}
}
}
#[derive(Clone)]
#[ani_rs::ani(path = "@ohos.request.request.agent.Mode")]
pub enum Mode {
Background,
Foreground,
}
impl From<Mode> for config::Mode {
fn from(value: Mode) -> Self {
match value {
Mode::Background => config::Mode::BackGround,
Mode::Foreground => config::Mode::FrontEnd,
}
}
}
impl From<config::Mode> for Mode {
fn from(value: config::Mode) -> Self {
match value {
config::Mode::BackGround => Mode::Background,
config::Mode::FrontEnd => Mode::Foreground,
}
}
}
impl From<u8> for Mode {
fn from(value: u8) -> Self {
match value {
0 => Mode::Background,
1 => Mode::Foreground,
_ => unimplemented!(),
}
}
}
#[derive(Clone)]
#[ani_rs::ani(path = "@ohos.request.request.agent.Network")]
pub enum Network {
Any,
Wifi,
Cellular,
}
impl From<Network> for NetworkConfig {
fn from(value: Network) -> Self {
match value {
Network::Any => NetworkConfig::Any,
Network::Wifi => NetworkConfig::Wifi,
Network::Cellular => NetworkConfig::Cellular,
}
}
}
impl From<NetworkConfig> for Network {
fn from(value: NetworkConfig) -> Self {
match value {
NetworkConfig::Any => Network::Any,
NetworkConfig::Wifi => Network::Wifi,
NetworkConfig::Cellular => Network::Cellular,
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.BroadcastEvent")]
pub enum BroadcastEvent {
Complete,
}
#[derive(Clone)]
#[ani_rs::ani(path = "@ohos.request.request.agent.FileSpecInner")]
pub struct FileSpec {
path: String,
content_type: Option<String>,
filename: Option<String>,
extras: Option<HashMap<String, String>>,
}
impl From<FileSpec> for request_core::file::FileSpec {
fn from(value: FileSpec) -> Self {
request_core::file::FileSpec {
name: "".to_string(),
path: value.path,
mime_type: value.content_type.unwrap_or("".to_string()),
file_name: value.filename.unwrap_or("".to_string()),
is_user_file: false,
fd: None,
}
}
}
#[derive(Serialize, Deserialize, Clone)]
pub enum Value {
S(String),
#[serde(rename = "@ohos.request.request.agent.FileSpec")]
FileSpec(FileSpec),
Array(Vec<FileSpec>),
}
#[derive(Clone)]
#[ani_rs::ani(path = "@ohos.request.request.agent.FormItemInner")]
pub struct FormItem {
name: String,
value: Value,
}
#[derive(Clone)]
#[ani_rs::ani(path = "@ohos.request.request.agent.NotificationInner")]
pub struct Notification<'local> {
pub title: Option<String>,
pub text: Option<String>,
pub disable: Option<bool>,
pub visibility: Option<i32>,
pub want_agent: Option<AniObject<'local>>,
}
impl From<Notification<'_>> for request_core::config::Notification {
fn from(value: Notification) -> Self {
request_core::config::Notification {
title: value.title,
text: value.text,
disable: value.disable,
visibility: value.visibility,
want_agent: None,
}
}
}
#[derive(Clone, Serialize)]
#[ani_rs::ani]
pub struct MinSpeed {
pub speed: i64,
pub duration: i32,
}
impl From<MinSpeed> for request_core::config::MinSpeed {
fn from(value: MinSpeed) -> Self {
request_core::config::MinSpeed {
speed: value.speed,
duration: value.duration as i64,
}
}
}
impl From<request_core::config::MinSpeed> for MinSpeed {
fn from(value: request_core::config::MinSpeed) -> Self {
MinSpeed {
speed: value.speed,
duration: value.duration as i32,
}
}
}
#[derive(Clone, Serialize)]
#[ani_rs::ani]
pub struct Timeout {
connection_timeout: Option<i32>,
total_timeout: Option<i32>,
}
impl From<Timeout> for request_core::config::Timeout {
fn from(value: Timeout) -> Self {
request_core::config::Timeout {
connection_timeout: value.connection_timeout.unwrap_or(60) as u64,
total_timeout: value.total_timeout.unwrap_or(604800) as u64,
}
}
}
impl From<request_core::config::Timeout> for Timeout {
fn from(value: request_core::config::Timeout) -> Self {
Timeout {
connection_timeout: Some(value.connection_timeout as i32),
total_timeout: Some(value.total_timeout as i32),
}
}
}
#[derive(Clone, Serialize, Deserialize)]
pub enum Data {
S(String),
Array(Vec<FormItem>),
}
#[derive(Clone)]
#[ani_rs::ani(path = "@ohos.request.request.agent.ConfigInner")]
pub struct Config<'local> {
pub action: Action,
pub url: String,
pub title: Option<String>,
pub description: Option<String>,
pub mode: Option<Mode>,
pub overwrite: Option<bool>,
pub method: Option<String>,
pub headers: Option<HashMap<String, String>>,
pub data: Option<Data>,
pub saveas: Option<String>,
pub network: Option<Network>,
pub metered: Option<bool>,
pub roaming: Option<bool>,
pub retry: Option<bool>,
pub redirect: Option<bool>,
pub proxy: Option<String>,
pub index: Option<i32>,
pub begins: Option<i64>,
pub ends: Option<i64>,
pub gauge: Option<bool>,
pub precise: Option<bool>,
pub token: Option<String>,
pub priority: Option<i32>,
pub extras: Option<HashMap<String, String>>,
pub multipart: Option<bool>,
pub notification: Option<Notification<'local>>,
pub min_speed: Option<MinSpeed>,
pub timeout: Option<Timeout>,
}
#[ani_rs::ani(path = "@ohos.request.request.agent.State")]
pub enum State {
Initialized = 0x00,
Waiting = 0x10,
Running = 0x20,
Retrying = 0x21,
Paused = 0x30,
Stopped = 0x31,
Completed = 0x40,
Failed = 0x41,
Removed = 0x50,
}
impl From<request_core::info::State> for State {
fn from(value: request_core::info::State) -> Self {
match value {
request_core::info::State::Initialized => State::Initialized,
request_core::info::State::Waiting => State::Waiting,
request_core::info::State::Running => State::Running,
request_core::info::State::Retrying => State::Retrying,
request_core::info::State::Paused => State::Paused,
request_core::info::State::Stopped => State::Stopped,
request_core::info::State::Completed => State::Completed,
request_core::info::State::Failed => State::Failed,
request_core::info::State::Removed => State::Removed,
_ => unimplemented!(),
}
}
}
impl From<State> for request_core::info::State {
fn from(value: State) -> Self {
match value {
State::Initialized => request_core::info::State::Initialized,
State::Waiting => request_core::info::State::Waiting,
State::Running => request_core::info::State::Running,
State::Retrying => request_core::info::State::Retrying,
State::Paused => request_core::info::State::Paused,
State::Stopped => request_core::info::State::Stopped,
State::Completed => request_core::info::State::Completed,
State::Failed => request_core::info::State::Failed,
State::Removed => request_core::info::State::Removed,
}
}
}
impl From<u8> for State {
fn from(value: u8) -> Self {
match value {
0x00 => State::Initialized,
0x10 => State::Waiting,
0x20 => State::Running,
0x21 => State::Retrying,
0x30 => State::Paused,
0x31 => State::Stopped,
0x40 => State::Completed,
0x41 => State::Failed,
0x50 => State::Removed,
_ => unimplemented!(),
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.ProgressInner")]
pub struct Progress {
state: State,
index: i32,
processed: i64,
sizes: Vec<i64>,
extras: Option<HashMap<String, String>>,
}
impl From<&request_core::info::Progress> for Progress {
fn from(value: &request_core::info::Progress) -> Self {
Progress {
state: value.state.clone().into(),
index: value.index as i32,
processed: value.total_processed as i64,
sizes: value.sizes.clone(),
extras: None,
}
}
}
impl From<&request_core::info::InfoProgress> for Progress {
fn from(value: &request_core::info::InfoProgress) -> Self {
Progress {
state: value.common_data.state.into(),
index: value.common_data.index as i32,
processed: value.common_data.total_processed as i64,
sizes: value.sizes.clone(),
extras: None,
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.Faults")]
pub enum Faults {
Others = 0xFF,
Disconnected = 0x00,
Timeout = 0x10,
Protocol = 0x20,
Param = 0x30,
Fsio = 0x40,
Dns = 0x50,
Tcp = 0x60,
Ssl = 0x70,
Redirect = 0x80,
LowSpeed = 0x90,
}
impl From<request_core::info::Faults> for Faults {
fn from(value: request_core::info::Faults) -> Self {
match value {
request_core::info::Faults::Others => Faults::Others,
request_core::info::Faults::Disconnected => Faults::Disconnected,
request_core::info::Faults::Timeout => Faults::Timeout,
request_core::info::Faults::Protocol => Faults::Protocol,
request_core::info::Faults::Param => Faults::Param,
request_core::info::Faults::Fsio => Faults::Fsio,
request_core::info::Faults::Dns => Faults::Dns,
request_core::info::Faults::Tcp => Faults::Tcp,
request_core::info::Faults::Ssl => Faults::Ssl,
request_core::info::Faults::Redirect => Faults::Redirect,
request_core::info::Faults::LowSpeed => Faults::LowSpeed,
_ => unimplemented!(),
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.WaitingReason")]
pub enum WaitingReason {
TaskQueueFull = 0x00,
NetworkNotMatch = 0x01,
AppBackground = 0x02,
UserInactivated = 0x03,
}
impl From<request_core::info::WaitingReason> for WaitingReason {
fn from(value: request_core::info::WaitingReason) -> Self {
match value {
info::WaitingReason::TASK_QUEUE_FULL => WaitingReason::TaskQueueFull,
info::WaitingReason::NETWORK_NOT_MATCH => WaitingReason::NetworkNotMatch,
info::WaitingReason::APP_BACKGROUND => WaitingReason::AppBackground,
info::WaitingReason::USER_INACTIVATED => WaitingReason::UserInactivated,
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.FilterInner")]
pub struct Filter {
pub bundle: Option<String>,
pub before: Option<i64>,
pub after: Option<i64>,
pub state: Option<State>,
pub action: Option<Action>,
pub mode: Option<Mode>,
}
impl From<Filter> for request_core::filter::SearchFilter {
fn from(value: Filter) -> Self {
request_core::filter::SearchFilter {
bundle_name: value.bundle,
before: value.before,
after: value.after,
state: value.state.map(|s| s.into()),
action: value.action.map(|a| a.into()),
mode: value.mode.map(|m| m.into()),
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.TaskInfoInner")]
pub struct TaskInfo {
pub uid: Option<String>,
pub bundle: Option<String>,
pub saveas: Option<String>,
pub url: Option<String>,
pub data: Option<Data>,
pub tid: String,
pub title: String,
pub description: String,
pub action: Action,
pub mode: Mode,
pub priority: i32,
pub mime_type: String,
pub progress: Progress,
pub gauge: bool,
pub ctime: i64,
pub mtime: i64,
pub retry: bool,
pub tries: i32,
pub faults: Faults,
pub reason: String,
pub extras: Option<HashMap<String, String>>,
}
impl From<request_core::info::TaskInfo> for TaskInfo {
fn from(value: request_core::info::TaskInfo) -> Self {
let saveas = if value.common_data.action == Action::Upload as u8 {
"".to_string()
} else {
value
.file_specs
.get(0)
.map(|x| x.path.clone())
.unwrap_or("".to_string())
};
TaskInfo {
uid: Some(value.common_data.uid.to_string()),
bundle: Some(value.bundle),
saveas: Some(saveas),
url: Some(value.url),
data: Some(Data::S(value.data)),
tid: value.common_data.task_id.to_string(),
title: value.title,
description: value.description,
action: value.common_data.action.into(),
mode: value.common_data.mode.into(),
priority: value.common_data.priority as i32,
mime_type: value.mime_type,
progress: Progress::from(&value.progress),
gauge: value.common_data.gauge,
ctime: value.common_data.ctime as i64,
mtime: value.common_data.mtime as i64,
retry: value.common_data.retry,
tries: value.common_data.tries as i32,
faults: request_core::info::Faults::from(request_core::info::Reason::from(
value.common_data.reason as u32,
))
.into(),
reason: value.common_data.reason.to_string(),
extras: Some(value.extras.clone()),
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.HttpResponseInner")]
pub struct HttpResponse {
version: String,
status_code: i32,
reason: String,
headers: HashMap<String, Vec<String>>,
}
impl From<&request_core::info::Response> for HttpResponse {
fn from(value: &request_core::info::Response) -> Self {
HttpResponse {
version: value.version.clone(),
status_code: value.status_code as i32,
reason: value.reason.clone(),
headers: value.headers.clone(),
}
}
}
#[ani_rs::ani(path = "@ohos.request.request.agent.TaskInner")]
pub struct Task<'local> {
pub tid: String,
pub config: Config<'local>,
}
#[ani_rs::ani(path = "@ohos.request.request.agent.GroupConfigInner")]
pub struct GroupConfig<'local> {
pub gauge: Option<bool>,
pub notification: Notification<'local>,
}
impl From<request_core::config::TaskConfig> for Config<'_> {
fn from(value: request_core::config::TaskConfig) -> Self {
Config {
action: Action::from(value.common_data.action),
url: value.url,
title: if value.title.is_empty() {
None
} else {
Some(value.title)
},
description: if value.description.is_empty() {
None
} else {
Some(value.description)
},
mode: Some(Mode::from(value.common_data.mode)),
overwrite: None,
method: if value.method == "GET" {
None
} else {
Some(value.method)
},
headers: if value.headers.is_empty() {
None
} else {
Some(value.headers)
},
data: Some(Data::S(value.data)),
saveas: None,
network: Some(value.common_data.network_config.into()),
metered: Some(value.common_data.metered),
roaming: Some(value.common_data.roaming),
retry: Some(value.common_data.retry),
redirect: Some(value.common_data.redirect),
proxy: if value.proxy.is_empty() {
None
} else {
Some(value.proxy)
},
index: Some(value.common_data.index as i32),
begins: Some(value.common_data.begins as i64),
ends: Some(value.common_data.ends),
gauge: Some(value.common_data.gauge),
precise: Some(value.common_data.precise),
token: if value.token.is_empty() {
None
} else {
Some(value.token)
},
priority: Some(value.common_data.priority as i32),
extras: if value.extras.is_empty() {
None
} else {
Some(value.extras)
},
multipart: Some(value.common_data.multipart),
notification: None,
min_speed: Some(MinSpeed::from(value.min_speed)),
timeout: Some(Timeout::from(value.timeout)),
}
}
}
impl From<Config<'_>> for TaskConfig {
fn from(value: Config) -> Self {
let mut form_items = vec![];
let mut file_specs = vec![];
let mut data = "".to_string();
let method;
if matches!(value.action, Action::Upload) {
method = match value.method {
Some(m) if m.to_uppercase() == "POST" => m,
_ => "PUT".to_string(),
};
if let Some(Data::Array(form_items_data)) = value.data {
for form_item in form_items_data {
match form_item.value {
Value::S(s) => {
form_items.push(request_core::config::FormItem {
name: form_item.name,
value: s,
});
}
Value::FileSpec(file_spec) => {
let mut file_spec: request_core::file::FileSpec = file_spec.into();
file_spec.name = form_item.name;
file_specs.push(file_spec);
}
Value::Array(file_spec_array) => {
for file_spec in file_spec_array {
let mut file_spec: request_core::file::FileSpec = file_spec.into();
file_spec.name = form_item.name.clone();
file_specs.push(file_spec);
}
}
}
}
}
} else {
method = match value.method {
Some(m) if m.to_uppercase() == "POST" => m,
_ => "GET".to_string(),
};
if let Some(Data::S(s)) = value.data {
data = s;
}
}
TaskConfig {
bundle: "".to_string(),
bundle_type: 0,
atomic_account: "".to_string(),
url: value.url,
title: value.title.unwrap_or("".to_string()),
description: value.description.unwrap_or_default(),
method: method,
headers: value.headers.unwrap_or_default(),
data,
token: value.token.unwrap_or("".to_string()),
proxy: value.proxy.unwrap_or("".to_string()),
certificate_pins: "".to_string(),
extras: value.extras.unwrap_or_default(),
version: Version::API10,
form_items,
file_specs,
body_file_paths: vec![],
certs_path: vec![],
common_data: CommonTaskConfig {
task_id: 0,
uid: 0,
token_id: 0,
action: value.action.into(),
cover: false,
network_config: value
.network
.map(|n| n.into())
.unwrap_or(NetworkConfig::Any),
metered: value.metered.unwrap_or(false),
roaming: value.roaming.unwrap_or(true),
retry: value.retry.unwrap_or(true),
redirect: value.redirect.unwrap_or(true),
index: value.index.map(|i| i as u32).unwrap_or(0u32),
begins: value
.begins
.map(|b| if b > 0 { b as u64 } else { 0u64 })
.unwrap_or(0u64),
ends: value.ends.unwrap_or(-1),
gauge: value.gauge.unwrap_or(false),
precise: value.precise.unwrap_or(false),
priority: value.priority.map(|p| p as u32).unwrap_or(0u32),
background: !matches!(value.mode, Some(Mode::Foreground)),
multipart: value.multipart.unwrap_or(false),
mode: value.mode.unwrap_or(Mode::Background).into(),
min_speed: config::MinSpeed {
speed: 0,
duration: 0,
},
timeout: config::Timeout {
connection_timeout: 0,
total_timeout: 0,
},
},
saveas: value.saveas.unwrap_or_default(),
overwrite: value.overwrite.unwrap_or(false),
notification: value.notification.map(Into::into).unwrap_or(
request_core::config::Notification {
title: None,
text: None,
disable: None,
visibility: None,
want_agent: None,
},
),
min_speed: value
.min_speed
.unwrap_or(MinSpeed {
speed: 0,
duration: 0,
})
.into(),
timeout: value
.timeout
.unwrap_or(Timeout {
connection_timeout: Some(60),
total_timeout: Some(604800),
})
.into(),
}
}
}