mirror of
https://github.com/wisdgod/cursor-api.git
synced 2025-12-24 13:38:01 +08:00
refactor: Higher performance with trait static dispatch
This commit is contained in:
@@ -7,7 +7,7 @@ WORKDIR /app
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends build-essential protobuf-compiler nodejs npm musl-tools && rm -rf /var/lib/apt/lists/* && case "$TARGETARCH" in amd64) rustup target add x86_64-unknown-linux-musl ;; arm64) rustup target add aarch64-unknown-linux-musl ;; *) echo "Unsupported architecture for rustup: $TARGETARCH" && exit 1 ;; esac
|
||||
|
||||
COPY . .
|
||||
RUN case "$TARGETARCH" in amd64) TARGET_TRIPLE="x86_64-unknown-linux-musl"; TARGET_CPU="x86-64-v3" ;; arm64) TARGET_TRIPLE="aarch64-unknown-linux-musl"; TARGET_CPU="neoverse-n1" ;; *) echo "Unsupported architecture: $TARGETARCH" && exit 1 ;; esac && cargo build --bin cursor-api --release --target=$TARGET_TRIPLE -- -C link-arg=-s -C target-feature=+crt-static -C target-cpu=$TARGET_CPU -A unused && cp target/$TARGET_TRIPLE/release/cursor-api /app/cursor-api
|
||||
RUN case "$TARGETARCH" in amd64) TARGET_TRIPLE="x86_64-unknown-linux-musl"; TARGET_CPU="x86-64-v3" ;; arm64) TARGET_TRIPLE="aarch64-unknown-linux-musl"; TARGET_CPU="neoverse-n1" ;; *) echo "Unsupported architecture: $TARGETARCH" && exit 1 ;; esac && RUSTFLAGS="-C link-arg=-s -C target-feature=+crt-static -C target-cpu=$TARGET_CPU -A unused" cargo build --bin cursor-api --release --target=$TARGET_TRIPLE && cp target/$TARGET_TRIPLE/release/cursor-api /app/cursor-api
|
||||
|
||||
# 运行阶段
|
||||
FROM scratch
|
||||
|
||||
@@ -229,7 +229,7 @@ pub fn init_thinking_tags() {
|
||||
return;
|
||||
}
|
||||
|
||||
let tag = crate::common::utils::parse_string_from_env("THINKING_TAG", DEFAULT_THINKING_TAG);
|
||||
let tag = crate::common::utils::parse_from_env("THINKING_TAG", DEFAULT_THINKING_TAG);
|
||||
|
||||
if tag == DEFAULT_THINKING_TAG {
|
||||
return;
|
||||
|
||||
@@ -102,7 +102,7 @@ pub fn header_value_ua_cursor_latest() -> http::header::HeaderValue {
|
||||
pub fn initialize_cursor_version() {
|
||||
use ::core::ops::Deref as _;
|
||||
|
||||
let version = crate::common::utils::parse_string_from_env(
|
||||
let version = crate::common::utils::parse_from_env(
|
||||
ENV_CURSOR_CLIENT_VERSION,
|
||||
DEFAULT_CLIENT_VERSION,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
pub mod log;
|
||||
|
||||
use ::std::{
|
||||
borrow::Cow,
|
||||
path::PathBuf,
|
||||
sync::{LazyLock, OnceLock},
|
||||
};
|
||||
|
||||
use super::{
|
||||
constant::{
|
||||
CURSOR_API2_HOST, CURSOR_API4_HOST, CURSOR_GCPP_ASIA_HOST, CURSOR_GCPP_EU_HOST,
|
||||
@@ -7,12 +13,7 @@ use super::{
|
||||
},
|
||||
model::{DateTime, GcppHost},
|
||||
};
|
||||
use crate::common::utils::{parse_bool_from_env, parse_string_from_env, parse_usize_from_env};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
path::PathBuf,
|
||||
sync::{LazyLock, OnceLock},
|
||||
};
|
||||
use crate::common::utils::parse_from_env;
|
||||
|
||||
macro_rules! def_pub_static {
|
||||
// 基础版本:直接存储 String
|
||||
@@ -23,7 +24,7 @@ macro_rules! def_pub_static {
|
||||
// 环境变量版本
|
||||
($name:ident,env: $env_key:expr,default: $default:expr) => {
|
||||
pub static $name: LazyLock<Cow<'static, str>> =
|
||||
LazyLock::new(|| parse_string_from_env($env_key, $default));
|
||||
LazyLock::new(|| parse_from_env($env_key, $default));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,7 +39,7 @@ pub fn get_start_time() -> &'static chrono::NaiveDateTime {
|
||||
|
||||
pub static GENERAL_TIMEZONE: LazyLock<chrono_tz::Tz> = LazyLock::new(|| {
|
||||
use std::str::FromStr as _;
|
||||
let tz = parse_string_from_env("GENERAL_TIMEZONE", EMPTY_STRING);
|
||||
let tz = parse_from_env("GENERAL_TIMEZONE", EMPTY_STRING);
|
||||
if tz.is_empty() {
|
||||
__eprintln!(
|
||||
"未配置时区,请在环境变量GENERAL_TIMEZONE中设置,格式如'Asia/Shanghai'\n将使用默认时区: Asia/Shanghai"
|
||||
@@ -64,7 +65,7 @@ pub fn get_default_instructions(now_with_tz: chrono::DateTime<chrono_tz::Tz>) ->
|
||||
}
|
||||
|
||||
pub static GENERAL_GCPP_HOST: LazyLock<GcppHost> = LazyLock::new(|| {
|
||||
let gcpp_host = parse_string_from_env("GENERAL_GCPP_HOST", EMPTY_STRING);
|
||||
let gcpp_host = parse_from_env("GENERAL_GCPP_HOST", EMPTY_STRING);
|
||||
let gcpp_host = gcpp_host.trim();
|
||||
if gcpp_host.is_empty() {
|
||||
__eprintln!(
|
||||
@@ -276,7 +277,7 @@ def_cursor_api_url!(
|
||||
);
|
||||
|
||||
static DATA_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
let data_dir = parse_string_from_env("DATA_DIR", "data");
|
||||
let data_dir = parse_from_env("DATA_DIR", "data");
|
||||
let path = std::env::current_exe()
|
||||
.ok()
|
||||
.and_then(|exe_path| exe_path.parent().map(|p| p.to_path_buf()))
|
||||
@@ -306,7 +307,7 @@ const DEFAULT_TCP_KEEPALIVE: usize = 90;
|
||||
const MAX_TCP_KEEPALIVE: u64 = 600;
|
||||
|
||||
pub static TCP_KEEPALIVE: LazyLock<u64> = LazyLock::new(|| {
|
||||
let keepalive = parse_usize_from_env("TCP_KEEPALIVE", DEFAULT_TCP_KEEPALIVE);
|
||||
let keepalive = parse_from_env("TCP_KEEPALIVE", DEFAULT_TCP_KEEPALIVE);
|
||||
u64::try_from(keepalive)
|
||||
.map(|t| t.min(MAX_TCP_KEEPALIVE))
|
||||
.unwrap_or(DEFAULT_TCP_KEEPALIVE as u64)
|
||||
@@ -316,13 +317,13 @@ const DEFAULT_SERVICE_TIMEOUT: usize = 30;
|
||||
const MAX_SERVICE_TIMEOUT: u64 = 600;
|
||||
|
||||
pub static SERVICE_TIMEOUT: LazyLock<u64> = LazyLock::new(|| {
|
||||
let timeout = parse_usize_from_env("SERVICE_TIMEOUT", DEFAULT_SERVICE_TIMEOUT);
|
||||
let timeout = parse_from_env("SERVICE_TIMEOUT", DEFAULT_SERVICE_TIMEOUT);
|
||||
u64::try_from(timeout)
|
||||
.map(|t| t.min(MAX_SERVICE_TIMEOUT))
|
||||
.unwrap_or(DEFAULT_SERVICE_TIMEOUT as u64)
|
||||
});
|
||||
|
||||
pub static REAL_USAGE: LazyLock<bool> = LazyLock::new(|| parse_bool_from_env("REAL_USAGE", true));
|
||||
pub static REAL_USAGE: LazyLock<bool> = LazyLock::new(|| parse_from_env("REAL_USAGE", true));
|
||||
|
||||
// pub static TOKEN_VALIDITY_RANGE: LazyLock<TokenValidityRange> = LazyLock::new(|| {
|
||||
// let short = if let Ok(Ok(validity)) = std::env::var("TOKEN_SHORT_VALIDITY")
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
sync::{Arc, atomic::AtomicU64},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use tokio::{
|
||||
use ::core::{sync::atomic::AtomicU64, time::Duration};
|
||||
use ::std::{borrow::Cow, sync::Arc};
|
||||
use ::tokio::{
|
||||
fs::File,
|
||||
io::AsyncWriteExt as _,
|
||||
sync::{
|
||||
@@ -15,10 +11,7 @@ use tokio::{
|
||||
task::JoinHandle,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
common::utils::{parse_bool_from_env, parse_string_from_env},
|
||||
leak::manually_init::ManuallyInit,
|
||||
};
|
||||
use crate::{common::utils::parse_from_env, leak::manually_init::ManuallyInit};
|
||||
|
||||
// --- 全局配置 ---
|
||||
|
||||
@@ -30,8 +23,8 @@ static DEBUG_LOG_FILE: ManuallyInit<Cow<'static, str>> = ManuallyInit::new();
|
||||
#[forbid(unused)]
|
||||
pub fn init() {
|
||||
unsafe {
|
||||
DEBUG.init(parse_bool_from_env("DEBUG", true));
|
||||
DEBUG_LOG_FILE.init(parse_string_from_env("DEBUG_LOG_FILE", "debug.log"));
|
||||
DEBUG.init(parse_from_env("DEBUG", true));
|
||||
DEBUG_LOG_FILE.init(parse_from_env("DEBUG_LOG_FILE", "debug.log"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
lazy::CONFIG_FILE_PATH,
|
||||
model::FetchMode,
|
||||
},
|
||||
common::utils::{parse_bool_from_env, parse_string_from_env},
|
||||
common::utils::parse_from_env,
|
||||
leak::manually_init::ManuallyInit,
|
||||
};
|
||||
|
||||
@@ -123,16 +123,15 @@ impl AppConfig {
|
||||
|
||||
let mut config = APP_CONFIG.write();
|
||||
config.vision_ability =
|
||||
VisionAbility::from_str(&parse_string_from_env("VISION_ABILITY", EMPTY_STRING));
|
||||
config.slow_pool = parse_bool_from_env("ENABLE_SLOW_POOL", false);
|
||||
config.long_context = parse_bool_from_env("ENABLE_LONG_CONTEXT", false);
|
||||
config.usage_check =
|
||||
UsageCheck::from_str(&parse_string_from_env("USAGE_CHECK", EMPTY_STRING));
|
||||
config.dynamic_key = parse_bool_from_env("DYNAMIC_KEY", false);
|
||||
config.share_token = parse_string_from_env("SHARED_TOKEN", EMPTY_STRING).into_owned();
|
||||
config.web_refs = parse_bool_from_env("INCLUDE_WEB_REFERENCES", false);
|
||||
VisionAbility::from_str(&parse_from_env("VISION_ABILITY", EMPTY_STRING));
|
||||
config.slow_pool = parse_from_env("ENABLE_SLOW_POOL", false);
|
||||
config.long_context = parse_from_env("ENABLE_LONG_CONTEXT", false);
|
||||
config.usage_check = UsageCheck::from_str(&parse_from_env("USAGE_CHECK", EMPTY_STRING));
|
||||
config.dynamic_key = parse_from_env("DYNAMIC_KEY", false);
|
||||
config.share_token = parse_from_env("SHARED_TOKEN", EMPTY_STRING).into_owned();
|
||||
config.web_refs = parse_from_env("INCLUDE_WEB_REFERENCES", false);
|
||||
config.fetch_models =
|
||||
FetchMode::from_str(&parse_string_from_env("FETCH_RAW_MODELS", EMPTY_STRING));
|
||||
FetchMode::from_str(&parse_from_env("FETCH_RAW_MODELS", EMPTY_STRING));
|
||||
}
|
||||
|
||||
config_methods! {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use rand::{
|
||||
use ::core::{fmt, str::FromStr};
|
||||
use ::rand::{
|
||||
RngCore as _,
|
||||
distr::{Distribution, StandardUniform},
|
||||
};
|
||||
use sha2::Digest as _;
|
||||
use std::{fmt, str::FromStr};
|
||||
use ::sha2::Digest as _;
|
||||
|
||||
use crate::common::utils::hex::HEX_CHARS;
|
||||
|
||||
static mut SAFE_HASH: bool = false;
|
||||
|
||||
pub(super) fn init_hash() {
|
||||
unsafe { SAFE_HASH = crate::common::utils::parse_bool_from_env("SAFE_HASH", true) }
|
||||
unsafe { SAFE_HASH = crate::common::utils::parse_from_env("SAFE_HASH", true) }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -79,7 +79,7 @@ impl LogManager {
|
||||
/// 从存储中加载日志
|
||||
#[inline(never)]
|
||||
pub async fn load() -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let logs_limit = RequestLogsLimit::from_usize(crate::common::utils::parse_usize_from_env(
|
||||
let logs_limit = RequestLogsLimit::from_usize(crate::common::utils::parse_from_env(
|
||||
"REQUEST_LOGS_LIMIT",
|
||||
100,
|
||||
));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::{common::utils::parse_string_from_env, leak::manually_init::ManuallyInit};
|
||||
use crate::{common::utils::parse_from_env, leak::manually_init::ManuallyInit};
|
||||
|
||||
pub static TZ: ManuallyInit<chrono_tz::Tz> = ManuallyInit::new();
|
||||
|
||||
#[inline(always)]
|
||||
pub fn __init() {
|
||||
use std::str::FromStr as _;
|
||||
let tz = match chrono_tz::Tz::from_str(&parse_string_from_env("TZ", super::EMPTY_STRING)) {
|
||||
let tz = match chrono_tz::Tz::from_str(&parse_from_env("TZ", super::EMPTY_STRING)) {
|
||||
Ok(tz) => tz,
|
||||
Err(_e) => chrono_tz::Tz::UTC,
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ use reqwest::{
|
||||
},
|
||||
};
|
||||
|
||||
trait RequestBuilderExt {
|
||||
trait RequestBuilderExt: Sized {
|
||||
fn opt_header<K, V>(self, key: K, value: Option<V>) -> Self
|
||||
where
|
||||
http::HeaderName: TryFrom<K>,
|
||||
|
||||
4
src/common/impls.rs
Normal file
4
src/common/impls.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
// pub trait ToBufStr: Copy {
|
||||
// const BUF_SIZE: usize;
|
||||
// fn to_str<'buf>(&self, buf: &'buf mut [u8; Self::BUF_SIZE]) -> &'buf mut str;
|
||||
// }
|
||||
1423
src/common/utils.rs
1423
src/common/utils.rs
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ use ::std::borrow::Cow;
|
||||
|
||||
mod private {
|
||||
use std::borrow::Cow;
|
||||
pub trait Sealed {}
|
||||
pub trait Sealed: Sized {}
|
||||
|
||||
impl Sealed for &str {}
|
||||
impl Sealed for String {}
|
||||
@@ -22,9 +22,9 @@ mod private {
|
||||
|
||||
/// A trait representing types that can be appended to a `StringBuilder`.
|
||||
/// This is a sealed trait and cannot be implemented for types outside this crate.
|
||||
pub trait StringPart<'a>: private::Sealed + Into<Cow<'a, str>> + Debug + Clone {}
|
||||
pub trait StringPart<'a>: private::Sealed + Into<Cow<'a, str>> {}
|
||||
|
||||
impl<'a, T> StringPart<'a> for T where T: private::Sealed + Into<Cow<'a, str>> + Debug + Clone {}
|
||||
impl<'a, T> StringPart<'a> for T where T: private::Sealed + Into<Cow<'a, str>> {}
|
||||
|
||||
/// Internal storage state for StringBuilder
|
||||
///
|
||||
|
||||
@@ -128,11 +128,11 @@ fn extract_web_references_info(text: &str) -> (String, Vec<WebReference>, bool)
|
||||
}
|
||||
}
|
||||
|
||||
const trait ToOpt: Copy {
|
||||
trait ToOpt: Copy {
|
||||
fn to_opt(self) -> Option<Self>;
|
||||
}
|
||||
|
||||
impl const ToOpt for bool {
|
||||
impl ToOpt for bool {
|
||||
#[inline(always)]
|
||||
fn to_opt(self) -> Option<Self> { if self { Some(true) } else { None } }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ static mut BYPASS_MODEL_VALIDATION: bool = false;
|
||||
pub fn init_resolver() {
|
||||
unsafe {
|
||||
BYPASS_MODEL_VALIDATION =
|
||||
crate::common::utils::parse_bool_from_env("BYPASS_MODEL_VALIDATION", false)
|
||||
crate::common::utils::parse_from_env("BYPASS_MODEL_VALIDATION", false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use std::{
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
pub trait InstantExt {
|
||||
pub trait InstantExt: Sized {
|
||||
fn duration_as_secs_f32(&mut self) -> f32;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use ::bytes::{Buf as _, BytesMut};
|
||||
use ::prost::Message as _;
|
||||
|
||||
use super::decompress_gzip;
|
||||
use crate::core::{aiserver::v1::StreamCppResponse, error::StreamError};
|
||||
use bytes::{Buf as _, BytesMut};
|
||||
use prost::Message as _;
|
||||
|
||||
#[derive(::serde::Serialize, PartialEq, Clone)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// use bytes::{Buf as _, BytesMut};
|
||||
// use ::bytes::{Buf as _, BytesMut};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use ::std::borrow::Cow;
|
||||
|
||||
use super::{
|
||||
decompress_gzip,
|
||||
@@ -45,7 +45,7 @@ use super::{
|
||||
|
||||
// if let Ok(msg) = T::decode(&self.buf[..]) {
|
||||
// return Ok(Some(DecodedMessage::Protobuf(msg)));
|
||||
// } else if let Some(text) = String::from_utf8(self.buf.to_vec()) {
|
||||
// } else if let Ok(text) = String::from_utf8(self.buf.to_vec()) {
|
||||
// return Ok(Some(DecodedMessage::Text(text)));
|
||||
// }
|
||||
// }
|
||||
@@ -92,7 +92,7 @@ pub fn decode<T: ProtobufMessage>(data: &[u8]) -> Result<DecodedMessage<T>, Deco
|
||||
|
||||
if let Ok(msg) = T::decode(&*decompressed) {
|
||||
return Ok(DecodedMessage::Protobuf(msg));
|
||||
} else if let Some(text) = super::utils::string_from_utf8_cow(decompressed) {
|
||||
} else if let Some(text) = super::utils::string_from_utf8(decompressed) {
|
||||
return Ok(DecodedMessage::Text(text));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use prost::Message;
|
||||
use ::prost::Message;
|
||||
|
||||
/// 表示可以被Protobuf编解码并可创建默认实例的消息类型
|
||||
pub trait ProtobufMessage: Message + Default {}
|
||||
@@ -32,6 +32,7 @@ pub enum DecodedMessage<T: ProtobufMessage> {
|
||||
}
|
||||
|
||||
// impl<T: ProtobufMessage> DecodedMessage<T> {
|
||||
// #[inline]
|
||||
// pub fn encode(&self) -> Vec<u8>
|
||||
// where
|
||||
// Self: Sized,
|
||||
@@ -43,8 +44,8 @@ pub enum DecodedMessage<T: ProtobufMessage> {
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl<T: ProtobufMessage> std::fmt::Debug for DecodedMessage<T> {
|
||||
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// impl<T: ProtobufMessage> ::core::fmt::Debug for DecodedMessage<T> {
|
||||
// fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||
// match self {
|
||||
// Self::Protobuf(msg) => write!(f, "\n{msg:#?}"),
|
||||
// Self::Text(s) => write!(f, "\n{s:?}"),
|
||||
@@ -52,8 +53,8 @@ pub enum DecodedMessage<T: ProtobufMessage> {
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl<T: ProtobufMessage + serde::Serialize> std::fmt::Display for DecodedMessage<T> {
|
||||
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// impl<T: ProtobufMessage + ::serde::Serialize> ::core::fmt::Display for DecodedMessage<T> {
|
||||
// fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||
// match self {
|
||||
// Self::Protobuf(msg) => write!(f, "\n{}", serde_json::to_string(msg).unwrap()),
|
||||
// Self::Text(s) => write!(f, "\n{s}"),
|
||||
|
||||
@@ -1,17 +1,36 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[allow(private_bounds)]
|
||||
#[inline]
|
||||
pub fn string_from_utf8(v: &[u8]) -> Option<String> {
|
||||
match ::core::str::from_utf8(v) {
|
||||
Ok(_) => Some(unsafe { String::from_utf8_unchecked(v.to_vec()) }),
|
||||
pub fn string_from_utf8<V: StringFrom>(v: V) -> Option<String> {
|
||||
match ::core::str::from_utf8(v.as_bytes()) {
|
||||
Ok(_) => Some(unsafe { String::from_utf8_unchecked(v.into_vec()) }),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn string_from_utf8_cow(v: Cow<'_, [u8]>) -> Option<String> {
|
||||
match ::core::str::from_utf8(&v) {
|
||||
Ok(_) => Some(unsafe { String::from_utf8_unchecked(v.into_owned()) }),
|
||||
Err(_) => None,
|
||||
}
|
||||
trait StringFrom: Sized {
|
||||
fn as_bytes(&self) -> &[u8];
|
||||
fn into_vec(self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
impl StringFrom for &[u8] {
|
||||
#[inline(always)]
|
||||
fn as_bytes(&self) -> &[u8] { *self }
|
||||
#[inline(always)]
|
||||
fn into_vec(self) -> Vec<u8> { self.to_vec() }
|
||||
}
|
||||
|
||||
impl StringFrom for Cow<'_, [u8]> {
|
||||
#[inline(always)]
|
||||
fn as_bytes(&self) -> &[u8] { self }
|
||||
#[inline(always)]
|
||||
fn into_vec(self) -> Vec<u8> { self.into_owned() }
|
||||
}
|
||||
|
||||
// mod private {
|
||||
// pub trait Sealed: Sized {}
|
||||
|
||||
// impl Sealed for &[u8] {}
|
||||
// impl Sealed for super::Cow<'_, [u8]> {}
|
||||
// }
|
||||
|
||||
67
src/main.rs
67
src/main.rs
@@ -5,7 +5,8 @@
|
||||
hasher_prefixfree_extras,
|
||||
const_trait_impl,
|
||||
const_default,
|
||||
core_intrinsics
|
||||
core_intrinsics,
|
||||
associated_type_defaults
|
||||
)]
|
||||
#![allow(clippy::redundant_static_lifetimes)]
|
||||
|
||||
@@ -18,6 +19,34 @@ mod core;
|
||||
mod leak;
|
||||
mod natural_args;
|
||||
|
||||
use ::axum::{
|
||||
Router, middleware,
|
||||
routing::{get, post},
|
||||
};
|
||||
use ::tokio::signal;
|
||||
use ::tower_http::{cors::CorsLayer, limit::RequestBodyLimitLayer};
|
||||
|
||||
use app::{
|
||||
config::handle_config_update,
|
||||
constant::{
|
||||
EMPTY_STRING, EXE_NAME, ROUTE_ABOUT_PATH, ROUTE_API_PATH, ROUTE_BUILD_KEY_PATH,
|
||||
ROUTE_CONFIG_PATH, ROUTE_CONFIG_VERSION_GET_PATH, ROUTE_CPP_CONFIG_PATH,
|
||||
ROUTE_CPP_MODELS_PATH, ROUTE_CPP_STREAM_PATH, ROUTE_ENV_EXAMPLE_PATH, ROUTE_FILE_SYNC_PATH,
|
||||
ROUTE_FILE_UPLOAD_PATH, ROUTE_GEN_CHECKSUM, ROUTE_GEN_HASH, ROUTE_GEN_TOKEN,
|
||||
ROUTE_GEN_UUID, ROUTE_GET_TIMESTAMP_HEADER, ROUTE_HEALTH_PATH, ROUTE_LOGS_GET_PATH,
|
||||
ROUTE_LOGS_PATH, ROUTE_LOGS_TOKENS_GET_PATH, ROUTE_PROXIES_ADD_PATH,
|
||||
ROUTE_PROXIES_DELETE_PATH, ROUTE_PROXIES_GET_PATH, ROUTE_PROXIES_PATH,
|
||||
ROUTE_PROXIES_SET_GENERAL_PATH, ROUTE_PROXIES_SET_PATH, ROUTE_README_PATH, ROUTE_ROOT_PATH,
|
||||
ROUTE_STATIC_PATH, ROUTE_TOKENS_ADD_PATH, ROUTE_TOKENS_ALIAS_SET_PATH,
|
||||
ROUTE_TOKENS_CONFIG_VERSION_UPDATE_PATH, ROUTE_TOKENS_DELETE_PATH, ROUTE_TOKENS_GET_PATH,
|
||||
ROUTE_TOKENS_PATH, ROUTE_TOKENS_PROFILE_UPDATE_PATH, ROUTE_TOKENS_PROXY_SET_PATH,
|
||||
ROUTE_TOKENS_REFRESH_PATH, ROUTE_TOKENS_SET_PATH, ROUTE_TOKENS_STATUS_SET_PATH,
|
||||
ROUTE_TOKENS_TIMEZONE_SET_PATH, VERSION,
|
||||
},
|
||||
lazy::AUTH_TOKEN,
|
||||
model::{AppConfig, AppState},
|
||||
};
|
||||
use common::utils::parse_from_env;
|
||||
use core::{
|
||||
middleware::{admin_auth_middleware, cpp_auth_middleware, v1_auth_middleware},
|
||||
route::{
|
||||
@@ -40,34 +69,7 @@ use core::{
|
||||
handle_chat_completions, handle_messages, handle_models, handle_raw_models,
|
||||
},
|
||||
};
|
||||
use app::{
|
||||
config::handle_config_update,
|
||||
constant::{
|
||||
EMPTY_STRING, EXE_NAME, ROUTE_ABOUT_PATH, ROUTE_API_PATH, ROUTE_BUILD_KEY_PATH,
|
||||
ROUTE_CONFIG_PATH, ROUTE_CONFIG_VERSION_GET_PATH, ROUTE_CPP_CONFIG_PATH,
|
||||
ROUTE_CPP_MODELS_PATH, ROUTE_CPP_STREAM_PATH, ROUTE_ENV_EXAMPLE_PATH, ROUTE_FILE_SYNC_PATH,
|
||||
ROUTE_FILE_UPLOAD_PATH, ROUTE_GEN_CHECKSUM, ROUTE_GEN_HASH, ROUTE_GEN_TOKEN,
|
||||
ROUTE_GEN_UUID, ROUTE_GET_TIMESTAMP_HEADER, ROUTE_HEALTH_PATH, ROUTE_LOGS_GET_PATH,
|
||||
ROUTE_LOGS_PATH, ROUTE_LOGS_TOKENS_GET_PATH, ROUTE_PROXIES_ADD_PATH,
|
||||
ROUTE_PROXIES_DELETE_PATH, ROUTE_PROXIES_GET_PATH, ROUTE_PROXIES_PATH,
|
||||
ROUTE_PROXIES_SET_GENERAL_PATH, ROUTE_PROXIES_SET_PATH, ROUTE_README_PATH, ROUTE_ROOT_PATH,
|
||||
ROUTE_STATIC_PATH, ROUTE_TOKENS_ADD_PATH, ROUTE_TOKENS_ALIAS_SET_PATH,
|
||||
ROUTE_TOKENS_CONFIG_VERSION_UPDATE_PATH, ROUTE_TOKENS_DELETE_PATH, ROUTE_TOKENS_GET_PATH,
|
||||
ROUTE_TOKENS_PATH, ROUTE_TOKENS_PROFILE_UPDATE_PATH, ROUTE_TOKENS_PROXY_SET_PATH,
|
||||
ROUTE_TOKENS_REFRESH_PATH, ROUTE_TOKENS_SET_PATH, ROUTE_TOKENS_STATUS_SET_PATH,
|
||||
ROUTE_TOKENS_TIMEZONE_SET_PATH, VERSION,
|
||||
},
|
||||
lazy::AUTH_TOKEN,
|
||||
model::{AppConfig, AppState},
|
||||
};
|
||||
use axum::{
|
||||
Router, middleware,
|
||||
routing::{get, post},
|
||||
};
|
||||
use common::utils::{parse_string_from_env, parse_usize_from_env};
|
||||
use natural_args::{DEFAULT_LISTEN_HOST, ENV_HOST, ENV_PORT};
|
||||
use tokio::signal;
|
||||
use tower_http::{cors::CorsLayer, limit::RequestBodyLimitLayer};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
@@ -219,7 +221,6 @@ async fn main() {
|
||||
route_chat_completions_path,
|
||||
route_messages_path,
|
||||
) = {
|
||||
let route_prefix = parse_string_from_env("ROUTE_PREFIX", EMPTY_STRING);
|
||||
define_typed_constants! {
|
||||
&'static str => {
|
||||
RAW_MODELS_PATH = "/raw/models",
|
||||
@@ -228,9 +229,9 @@ async fn main() {
|
||||
MESSAGES_PATH = "/v1/messages",
|
||||
}
|
||||
}
|
||||
use ::std::borrow::Cow;
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
let route_prefix = parse_from_env("ROUTE_PREFIX", EMPTY_STRING);
|
||||
if route_prefix.is_empty() {
|
||||
(
|
||||
Cow::Borrowed(RAW_MODELS_PATH),
|
||||
@@ -361,7 +362,7 @@ async fn main() {
|
||||
post(handle_get_config_version),
|
||||
)
|
||||
// .route(ROUTE_TOKEN_UPGRADE_PATH, post(handle_token_upgrade))
|
||||
.layer(RequestBodyLimitLayer::new(parse_usize_from_env(
|
||||
.layer(RequestBodyLimitLayer::new(parse_from_env(
|
||||
"REQUEST_BODY_LIMIT",
|
||||
2_000_000,
|
||||
)))
|
||||
@@ -379,7 +380,7 @@ async fn main() {
|
||||
.unwrap_or(3000)
|
||||
};
|
||||
let addr = SocketAddr::new(
|
||||
IpAddr::parse_ascii(parse_string_from_env(ENV_HOST, DEFAULT_LISTEN_HOST).as_bytes())
|
||||
IpAddr::parse_ascii(parse_from_env(ENV_HOST, DEFAULT_LISTEN_HOST).as_bytes())
|
||||
.unwrap_or_else(|e| {
|
||||
__cold_path!(); // IP解析失败是错误路径
|
||||
eprintln!("无法解析IP: {e}");
|
||||
|
||||
Reference in New Issue
Block a user