devin15/cursor2api-rust
0
1mod checksum;2pub use checksum::*;3mod tokens;4pub use tokens::*;5 6use super::models::userinfo::{StripeProfile, TokenProfile, UsageProfile, UserProfile};7use crate::app::{8 constant::{FALSE, TRUE},9 lazy::{TOKEN_DELIMITER, TOKEN_DELIMITER_LEN},10};11 12pub fn parse_bool_from_env(key: &str, default: bool) -> bool {13 std::env::var(key)14 .ok()15 .map(|v| match v.to_lowercase().as_str() {16 TRUE | "1" => true,17 FALSE | "0" => false,18 _ => default,19 })20 .unwrap_or(default)21}22 23pub fn parse_string_from_env(key: &str, default: &str) -> String {24 std::env::var(key).unwrap_or_else(|_| default.to_string())25}26 27pub fn parse_ascii_char_from_env(key: &str, default: char) -> char {28 std::env::var(key)29 .ok()30 .and_then(|v| {31 let chars: Vec<char> = v.chars().collect();32 if chars.len() == 1 && chars[0].is_ascii() {33 Some(chars[0])34 } else {35 None36 }37 })38 .unwrap_or(default)39}40 41pub fn parse_usize_from_env(key: &str, default: usize) -> usize {42 std::env::var(key)43 .ok()44 .and_then(|v| v.parse().ok())45 .unwrap_or(default)46}47 48pub async fn get_token_profile(auth_token: &str) -> Option<TokenProfile> {49 let user_id = extract_user_id(auth_token)?;50 51 // 构建请求客户端52 let client = super::client::build_usage_client(&user_id, auth_token);53 54 // 发送请求并获取响应55 // let response = client.send().await.ok()?;56 // let bytes = response.bytes().await?;57 // println!("Raw response bytes: {:?}", bytes);58 // let usage = serde_json::from_str::<UsageProfile>(&text).ok()?;59 let usage = client60 .send()61 .await62 .ok()?63 .json::<UsageProfile>()64 .await65 .ok()?;66 67 let user = get_user_profile(auth_token).await?;68 69 // 从 Stripe 获取用户资料70 let stripe = get_stripe_profile(auth_token).await?;71 72 // 映射响应数据到 TokenProfile73 Some(TokenProfile {74 usage,75 user,76 stripe,77 })78}79 80pub async fn get_stripe_profile(auth_token: &str) -> Option<StripeProfile> {81 let client = super::client::build_profile_client(auth_token);82 let response = client83 .send()84 .await85 .ok()?86 .json::<StripeProfile>()87 .await88 .ok()?;89 Some(response)90}91 92pub async fn get_user_profile(auth_token: &str) -> Option<UserProfile> {93 let user_id = extract_user_id(auth_token)?;94 95 // 构建请求客户端96 let client = super::client::build_userinfo_client(&user_id, auth_token);97 98 // 发送请求并获取响应99 let user_profile = client.send().await.ok()?.json::<UserProfile>().await.ok()?;100 101 Some(user_profile)102}103 104pub fn validate_token_and_checksum(auth_token: &str) -> Option<(String, String)> {105 // 找最后一个逗号106 let comma_pos = auth_token.rfind(*TOKEN_DELIMITER)?;107 let (token_part, checksum) = auth_token.split_at(comma_pos);108 let checksum = &checksum[*TOKEN_DELIMITER_LEN..]; // 跳过逗号109 110 // 解析 token - 为了向前兼容,忽略最后一个:或%3A前的内容111 let colon_pos = token_part.rfind(':');112 let encoded_colon_pos = token_part.rfind("%3A");113 114 let token = match (colon_pos, encoded_colon_pos) {115 (None, None) => token_part, // 最简单的构成: token,checksum116 (Some(pos1), None) => &token_part[(pos1 + 1)..],117 (None, Some(pos2)) => &token_part[(pos2 + 3)..],118 (Some(pos1), Some(pos2)) => {119 let pos = pos1.max(pos2);120 let start = if pos == pos2 { pos + 3 } else { pos + 1 };121 &token_part[start..]122 }123 };124 125 // 验证 token 和 checksum 有效性126 if validate_token(token) && validate_checksum(checksum) {127 Some((token.to_string(), checksum.to_string()))128 } else {129 None130 }131}132 133pub fn extract_token(auth_token: &str) -> Option<String> {134 // 解析 token135 let token_part = match auth_token.rfind(*TOKEN_DELIMITER) {136 Some(pos) => &auth_token[..pos],137 None => auth_token,138 };139 140 // 向前兼容141 let colon_pos = token_part.rfind(':');142 let encoded_colon_pos = token_part.rfind("%3A");143 144 let token = match (colon_pos, encoded_colon_pos) {145 (None, None) => token_part,146 (Some(pos1), None) => &token_part[(pos1 + 1)..],147 (None, Some(pos2)) => &token_part[(pos2 + 3)..],148 (Some(pos1), Some(pos2)) => {149 let pos = pos1.max(pos2);150 let start = if pos == pos2 { pos + 3 } else { pos + 1 };151 &token_part[start..]152 }153 };154 155 // 验证 token 有效性156 if validate_token(token) {157 Some(token.to_string())158 } else {159 None160 }161}162 163pub fn format_time_ms(seconds: f64) -> f64 {164 (seconds * 1000.0).round() / 1000.0165}166 