65 lines
1.8 KiB
Rust
65 lines
1.8 KiB
Rust
use std::backtrace::Backtrace;
|
|
|
|
use nyquest::{AsyncClient, Body, Request, header::USER_AGENT};
|
|
|
|
mod model;
|
|
use model::{GetResponse, GetUserId};
|
|
use serde::Serialize;
|
|
|
|
pub struct QRCode<'a> {
|
|
pub qrcode_content: &'a str,
|
|
}
|
|
|
|
#[derive(Debug, snafu::Snafu, Serialize)]
|
|
pub enum QRLoginError {
|
|
#[snafu(display("QRCode expired [10mins]"))]
|
|
QRCodeExpired10,
|
|
#[snafu(display("QRCode expired [30mins]"))]
|
|
QRCodeExpired30,
|
|
#[snafu(display("Bad signature!"))]
|
|
BadSingature,
|
|
#[snafu(display("unknown error: {error_kind}"))]
|
|
Unknown { error_kind: i64 },
|
|
|
|
#[snafu(context(false))]
|
|
#[snafu(display("request error: {source}"))]
|
|
NyquestError {
|
|
#[serde(skip)]
|
|
source: nyquest::Error,
|
|
#[serde(skip)]
|
|
backtrace: Backtrace,
|
|
},
|
|
|
|
#[snafu(context(false))]
|
|
JSONError {
|
|
#[serde(skip)]
|
|
source: serde_json::error::Error,
|
|
#[serde(skip)]
|
|
backtrace: Backtrace,
|
|
},
|
|
}
|
|
|
|
impl QRCode<'_> {
|
|
pub async fn login(self, client: &AsyncClient) -> Result<i64, QRLoginError> {
|
|
let qr_code = &self.qrcode_content.as_bytes()[self.qrcode_content.len() - 64..];
|
|
let qr_code = String::from_utf8_lossy(qr_code);
|
|
|
|
let req = Request::post("http://ai.sys-allnet.cn/wc_aime/api/get_data")
|
|
.with_body(Body::json(&GetUserId::new(qr_code))?)
|
|
.with_header(USER_AGENT, "WC_AIME_LIB");
|
|
|
|
let resp = client.request(req).await?;
|
|
let resp: GetResponse = resp.json().await?;
|
|
|
|
let user_id = resp.user_id;
|
|
|
|
match resp.error_id {
|
|
0 => return Ok(user_id),
|
|
2 => Err(QRLoginError::QRCodeExpired10),
|
|
1 => Err(QRLoginError::QRCodeExpired30),
|
|
50 => Err(QRLoginError::BadSingature),
|
|
error_kind => Err(QRLoginError::Unknown { error_kind }),
|
|
}
|
|
}
|
|
}
|