use serde::{Deserialize, Serialize};
use crate::{
client::rest::KuCoinClient,
types::{
KuCoinResponse,
sup_account::{Expire, SubAccBalance, SubAccData, SubAccListData, SubAccRequest},
},
};
#[derive(Debug, Serialize)]
pub struct CreateSubAccRequest {
#[serde(rename = "subName")]
pub sub_name: String,
pub password: String,
pub access: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub remarks: Option<String>,
}
impl CreateSubAccRequest {
pub fn new(sub_name: &str, password: &str, access: &str) -> Self {
Self {
sub_name: sub_name.to_string(),
password: password.to_string(),
access: access.to_string(),
remarks: None,
}
}
}
#[derive(Debug, Deserialize)]
pub struct CreateSubAccData {
pub uid: u64,
#[serde(rename = "subName")]
pub sub_name: String,
pub remarks: Option<String>,
pub access: String,
}
impl SubAccRequest {
pub fn new(name: &str, remark: &str, passphrase: &str) -> Self {
SubAccRequest {
expire: None,
ip_whitelist: None,
passphrase: passphrase.to_string(),
permission: None,
remark: remark.to_string(),
sub_name: name.to_string(),
}
}
pub fn set_expire(mut self, day: Expire) -> Self {
self.expire = Some(day);
self
}
pub fn add_ipwhitelist(mut self, ip: &str) -> Self {
match self.ip_whitelist.as_mut() {
Some(ips) => {
ips.push(',');
ips.push_str(ip);
}
None => self.ip_whitelist = Some(ip.to_string()),
};
self
}
pub fn set_permission(mut self, permission: &str) -> Self {
self.permission = Some(permission.to_string());
self
}
}
pub struct SubAccHander<'a> {
pub client: &'a KuCoinClient,
}
impl<'a> SubAccHander<'a> {
pub async fn add_sub_acc(
&self,
request: CreateSubAccRequest,
) -> Result<KuCoinResponse<CreateSubAccData>, reqwest::Error> {
let endpoint = "/api/v2/sub/user/created";
let payload = serde_json::to_string(&request).unwrap();
self.client
.send::<KuCoinResponse<CreateSubAccData>>("POST", &payload, endpoint)
.await
}
pub async fn add_api(
&self,
request: SubAccRequest,
) -> Result<KuCoinResponse<SubAccData>, reqwest::Error> {
let enpoint: &str = "/api/v1/sub/api-key";
let payload = serde_json::to_string(&request).unwrap();
self.client
.send::<KuCoinResponse<SubAccData>>("POST", &payload, enpoint)
.await
}
pub async fn fetchall(&self) -> Result<KuCoinResponse<SubAccListData>, reqwest::Error> {
let endpoint = "/api/v2/sub/user";
self.client
.send::<KuCoinResponse<SubAccListData>>("GET", "", endpoint)
.await
}
pub async fn balance(
&self,
user_id: &str,
) -> Result<KuCoinResponse<SubAccBalance>, reqwest::Error> {
let endpoint = &format!("/api/v1/sub-accounts/{}", user_id);
self.client
.send::<KuCoinResponse<SubAccBalance>>("GET", "", endpoint)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_basic_request() {
let req = SubAccRequest::new("myuser", "remark", "pass123");
assert_eq!(req.sub_name, "myuser");
assert_eq!(req.passphrase, "pass123");
assert_eq!(req.ip_whitelist, None); }
#[test]
fn test_add_ip_whitelist() {
let req = SubAccRequest::new("u", "r", "p")
.add_ipwhitelist("192.168.1.1")
.add_ipwhitelist("10.0.0.1");
assert_eq!(req.ip_whitelist, Some("192.168.1.1,10.0.0.1".to_string()));
}
#[test]
fn test_full_builder_chain() {
let req = SubAccRequest::new("user", "remark", "pass")
.set_permission("General,Spot")
.add_ipwhitelist("1.1.1.1");
assert_eq!(req.permission, Some("General,Spot".to_string()));
assert_eq!(req.ip_whitelist, Some("1.1.1.1".to_string()));
}
}