Team Ai
Apppublic

devin15/cursor2api-rust

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
utils.rs166 linesDownload Raw Back to common
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