Skip to main content

wae_types/
value.rs

1//! 动态值类型定义
2
3use crate::{ValidationErrorKind, WaeError};
4use serde::{Deserialize, Serialize};
5use std::{collections::HashMap, fmt};
6
7/// 计费维度:四元矩阵 (输入文本, 输出文本, 输入像素, 输出像素)
8#[derive(Debug, Clone, Default, Serialize, Deserialize)]
9pub struct BillingDimensions {
10    /// 输入文本长度 (如字符数或 Token 数)
11    pub input_text: u64,
12    /// 输出文本长度
13    pub output_text: u64,
14    /// 输入像素数 (宽 * 高)
15    pub input_pixels: u64,
16    /// 输出像素数
17    pub output_pixels: u64,
18}
19
20/// 文本成本定义 (每百万 Tokens/字符)
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct TextCost {
23    /// 每百万单位的价格
24    pub per_million: crate::Decimal,
25}
26
27/// 图像成本定义 (每百万像素)
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct ImageCost {
30    /// 每百万像素的价格
31    pub per_million: crate::Decimal,
32}
33
34/// 四元矩阵成本配置
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct BillingCostConfig {
37    /// 输入文本成本 (每百万 Tokens)
38    pub input_text: TextCost,
39    /// 输出文本成本 (每百万 Tokens)
40    pub output_text: TextCost,
41    /// 输入图像成本 (每百万像素)
42    pub input_pixels: ImageCost,
43    /// 输出图像成本 (每百万像素)
44    pub output_pixels: ImageCost,
45}
46
47impl BillingCostConfig {
48    /// 计算总成本 (单位:Decimal)
49    ///
50    /// 计算公式: (消耗数量 / 1,000,000) * 每百万单价
51    pub fn calculate_total_cost(&self, usage: &BillingDimensions) -> crate::Decimal {
52        let million = crate::dec!(1_000_000);
53        let mut total = crate::Decimal::ZERO;
54
55        if usage.input_text > 0 {
56            total += (crate::Decimal::from(usage.input_text) / million) * self.input_text.per_million;
57        }
58        if usage.output_text > 0 {
59            total += (crate::Decimal::from(usage.output_text) / million) * self.output_text.per_million;
60        }
61        if usage.input_pixels > 0 {
62            total += (crate::Decimal::from(usage.input_pixels) / million) * self.input_pixels.per_million;
63        }
64        if usage.output_pixels > 0 {
65            total += (crate::Decimal::from(usage.output_pixels) / million) * self.output_pixels.per_million;
66        }
67
68        total
69    }
70}
71
72/// 动态值类型
73///
74/// 提供类似 JSON 的动态类型支持,用于:
75/// - 配置文件解析
76/// - API 响应处理
77/// - 数据库查询结果
78/// - 通用数据交换
79#[derive(Debug, Clone, PartialEq)]
80pub enum Value {
81    /// 空值
82    Null,
83    /// 布尔值
84    Bool(bool),
85    /// 64位整数
86    Integer(i64),
87    /// 64位浮点数
88    Float(f64),
89    /// 字符串
90    String(String),
91    /// 字节数组
92    Bytes(Vec<u8>),
93    /// 数组
94    Array(Vec<Value>),
95    /// 对象/映射
96    Object(HashMap<String, Value>),
97}
98
99impl Value {
100    /// 创建空值
101    pub fn null() -> Self {
102        Value::Null
103    }
104
105    /// 创建布尔值
106    pub fn bool(v: bool) -> Self {
107        Value::Bool(v)
108    }
109
110    /// 创建整数值
111    pub fn integer(v: i64) -> Self {
112        Value::Integer(v)
113    }
114
115    /// 创建浮点数值
116    pub fn float(v: f64) -> Self {
117        Value::Float(v)
118    }
119
120    /// 创建字符串值
121    pub fn string(v: impl Into<String>) -> Self {
122        Value::String(v.into())
123    }
124
125    /// 创建字节数组值
126    pub fn bytes(v: Vec<u8>) -> Self {
127        Value::Bytes(v)
128    }
129
130    /// 创建数组值
131    pub fn array(v: Vec<Value>) -> Self {
132        Value::Array(v)
133    }
134
135    /// 创建对象值
136    pub fn object(v: HashMap<String, Value>) -> Self {
137        Value::Object(v)
138    }
139
140    /// 检查是否为空值
141    pub fn is_null(&self) -> bool {
142        matches!(self, Value::Null)
143    }
144
145    /// 检查是否为布尔值
146    pub fn is_bool(&self) -> bool {
147        matches!(self, Value::Bool(_))
148    }
149
150    /// 检查是否为整数
151    pub fn is_integer(&self) -> bool {
152        matches!(self, Value::Integer(_))
153    }
154
155    /// 检查是否为浮点数
156    pub fn is_float(&self) -> bool {
157        matches!(self, Value::Float(_))
158    }
159
160    /// 检查是否为数值 (整数或浮点)
161    pub fn is_number(&self) -> bool {
162        matches!(self, Value::Integer(_) | Value::Float(_))
163    }
164
165    /// 检查是否为字符串
166    pub fn is_string(&self) -> bool {
167        matches!(self, Value::String(_))
168    }
169
170    /// 检查是否为数组
171    pub fn is_array(&self) -> bool {
172        matches!(self, Value::Array(_))
173    }
174
175    /// 检查是否为对象
176    pub fn is_object(&self) -> bool {
177        matches!(self, Value::Object(_))
178    }
179
180    /// 获取布尔值
181    pub fn as_bool(&self) -> Option<bool> {
182        match self {
183            Value::Bool(v) => Some(*v),
184            _ => None,
185        }
186    }
187
188    /// 获取整数值
189    pub fn as_integer(&self) -> Option<i64> {
190        match self {
191            Value::Integer(v) => Some(*v),
192            _ => None,
193        }
194    }
195
196    /// 获取浮点数值
197    pub fn as_float(&self) -> Option<f64> {
198        match self {
199            Value::Float(v) => Some(*v),
200            Value::Integer(v) => Some(*v as f64),
201            _ => None,
202        }
203    }
204
205    /// 获取字符串引用
206    pub fn as_str(&self) -> Option<&str> {
207        match self {
208            Value::String(v) => Some(v),
209            _ => None,
210        }
211    }
212
213    /// 获取数组引用
214    pub fn as_array(&self) -> Option<&Vec<Value>> {
215        match self {
216            Value::Array(v) => Some(v),
217            _ => None,
218        }
219    }
220
221    /// 获取可变数组引用
222    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
223        match self {
224            Value::Array(v) => Some(v),
225            _ => None,
226        }
227    }
228
229    /// 获取对象引用
230    pub fn as_object(&self) -> Option<&HashMap<String, Value>> {
231        match self {
232            Value::Object(v) => Some(v),
233            _ => None,
234        }
235    }
236
237    /// 获取可变对象引用
238    pub fn as_object_mut(&mut self) -> Option<&mut HashMap<String, Value>> {
239        match self {
240            Value::Object(v) => Some(v),
241            _ => None,
242        }
243    }
244
245    /// 从对象中获取字段值
246    pub fn get(&self, key: &str) -> Option<&Value> {
247        match self {
248            Value::Object(map) => map.get(key),
249            _ => None,
250        }
251    }
252
253    /// 从数组中获取索引值
254    pub fn get_index(&self, index: usize) -> Option<&Value> {
255        match self {
256            Value::Array(arr) => arr.get(index),
257            _ => None,
258        }
259    }
260
261    /// 转换为 JSON 字符串
262    pub fn to_json_string(&self) -> String {
263        match self {
264            Value::Null => "null".to_string(),
265            Value::Bool(v) => v.to_string(),
266            Value::Integer(v) => v.to_string(),
267            Value::Float(v) => v.to_string(),
268            Value::String(v) => format!("\"{}\"", v.replace('\\', "\\\\").replace('"', "\\\"")),
269            Value::Bytes(v) => {
270                let encoded = base64_encode(v);
271                format!("\"{}\"", encoded)
272            }
273            Value::Array(arr) => {
274                let items: Vec<String> = arr.iter().map(|v| v.to_json_string()).collect();
275                format!("[{}]", items.join(","))
276            }
277            Value::Object(map) => {
278                let items: Vec<String> = map.iter().map(|(k, v)| format!("\"{}\":{}", k, v.to_json_string())).collect();
279                format!("{{{}}}", items.join(","))
280            }
281        }
282    }
283
284    /// 从 JSON 字符串解析
285    pub fn from_json_str(s: &str) -> Result<Value, WaeError> {
286        parse_json_value(s.trim())
287    }
288
289    /// 深度克隆
290    pub fn deep_clone(&self) -> Value {
291        self.clone()
292    }
293
294    /// 合并两个值 (用于配置合并)
295    pub fn merge(&mut self, other: Value) {
296        match (self, other) {
297            (Value::Object(a), Value::Object(b)) => {
298                for (k, v) in b {
299                    if let Some(existing) = a.get_mut(&k) {
300                        existing.merge(v);
301                    }
302                    else {
303                        a.insert(k, v);
304                    }
305                }
306            }
307            (Value::Array(a), Value::Array(b)) => {
308                a.extend(b);
309            }
310            (self_val, other_val) => {
311                *self_val = other_val;
312            }
313        }
314    }
315}
316
317impl From<bool> for Value {
318    fn from(v: bool) -> Self {
319        Value::Bool(v)
320    }
321}
322
323impl From<i32> for Value {
324    fn from(v: i32) -> Self {
325        Value::Integer(v as i64)
326    }
327}
328
329impl From<i64> for Value {
330    fn from(v: i64) -> Self {
331        Value::Integer(v)
332    }
333}
334
335impl From<u64> for Value {
336    fn from(v: u64) -> Self {
337        Value::Integer(v as i64)
338    }
339}
340
341impl From<f64> for Value {
342    fn from(v: f64) -> Self {
343        Value::Float(v)
344    }
345}
346
347impl From<String> for Value {
348    fn from(v: String) -> Self {
349        Value::String(v)
350    }
351}
352
353impl From<&str> for Value {
354    fn from(v: &str) -> Self {
355        Value::String(v.to_string())
356    }
357}
358
359impl From<Vec<Value>> for Value {
360    fn from(v: Vec<Value>) -> Self {
361        Value::Array(v)
362    }
363}
364
365impl From<HashMap<String, Value>> for Value {
366    fn from(v: HashMap<String, Value>) -> Self {
367        Value::Object(v)
368    }
369}
370
371impl Serialize for Value {
372    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
373    where
374        S: serde::Serializer,
375    {
376        match self {
377            Value::Null => serializer.serialize_none(),
378            Value::Bool(v) => serializer.serialize_bool(*v),
379            Value::Integer(v) => serializer.serialize_i64(*v),
380            Value::Float(v) => serializer.serialize_f64(*v),
381            Value::String(v) => serializer.serialize_str(v),
382            Value::Bytes(v) => serializer.serialize_bytes(v),
383            Value::Array(v) => v.serialize(serializer),
384            Value::Object(v) => v.serialize(serializer),
385        }
386    }
387}
388
389impl<'de> Deserialize<'de> for Value {
390    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
391    where
392        D: serde::Deserializer<'de>,
393    {
394        struct ValueVisitor;
395
396        impl<'de> serde::de::Visitor<'de> for ValueVisitor {
397            type Value = Value;
398
399            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
400                formatter.write_str("a valid value")
401            }
402
403            fn visit_none<E>(self) -> Result<Value, E>
404            where
405                E: serde::de::Error,
406            {
407                Ok(Value::Null)
408            }
409
410            fn visit_unit<E>(self) -> Result<Value, E>
411            where
412                E: serde::de::Error,
413            {
414                Ok(Value::Null)
415            }
416
417            fn visit_bool<E>(self, v: bool) -> Result<Value, E>
418            where
419                E: serde::de::Error,
420            {
421                Ok(Value::Bool(v))
422            }
423
424            fn visit_i64<E>(self, v: i64) -> Result<Value, E>
425            where
426                E: serde::de::Error,
427            {
428                Ok(Value::Integer(v))
429            }
430
431            fn visit_u64<E>(self, v: u64) -> Result<Value, E>
432            where
433                E: serde::de::Error,
434            {
435                Ok(Value::Integer(v as i64))
436            }
437
438            fn visit_f64<E>(self, v: f64) -> Result<Value, E>
439            where
440                E: serde::de::Error,
441            {
442                Ok(Value::Float(v))
443            }
444
445            fn visit_str<E>(self, v: &str) -> Result<Value, E>
446            where
447                E: serde::de::Error,
448            {
449                Ok(Value::String(v.to_string()))
450            }
451
452            fn visit_string<E>(self, v: String) -> Result<Value, E>
453            where
454                E: serde::de::Error,
455            {
456                Ok(Value::String(v))
457            }
458
459            fn visit_bytes<E>(self, v: &[u8]) -> Result<Value, E>
460            where
461                E: serde::de::Error,
462            {
463                Ok(Value::Bytes(v.to_vec()))
464            }
465
466            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Value, E>
467            where
468                E: serde::de::Error,
469            {
470                Ok(Value::Bytes(v))
471            }
472
473            fn visit_seq<A>(self, mut seq: A) -> Result<Value, A::Error>
474            where
475                A: serde::de::SeqAccess<'de>,
476            {
477                let mut arr = Vec::new();
478                while let Some(v) = seq.next_element()? {
479                    arr.push(v);
480                }
481                Ok(Value::Array(arr))
482            }
483
484            fn visit_map<A>(self, mut map: A) -> Result<Value, A::Error>
485            where
486                A: serde::de::MapAccess<'de>,
487            {
488                let mut obj = HashMap::new();
489                while let Some((k, v)) = map.next_entry()? {
490                    obj.insert(k, v);
491                }
492                Ok(Value::Object(obj))
493            }
494        }
495
496        deserializer.deserialize_any(ValueVisitor)
497    }
498}
499
500/// JSON 解析器
501fn parse_json_value(s: &str) -> Result<Value, WaeError> {
502    let (value, remaining) = parse_value(s.trim())?;
503    if !remaining.trim().is_empty() {
504        return Err(ValidationErrorKind::CustomValidation {
505            field: "json".to_string(),
506            message: format!("Unexpected characters after JSON: {}", remaining),
507        }
508        .into());
509    }
510    Ok(value)
511}
512
513fn parse_value(s: &str) -> Result<(Value, &str), WaeError> {
514    let s = s.trim_start();
515
516    if s.is_empty() {
517        return Err(ValidationErrorKind::CustomValidation {
518            field: "json".to_string(),
519            message: "Unexpected end of input".to_string(),
520        }
521        .into());
522    }
523
524    if let Some(stripped) = s.strip_prefix("null") {
525        return Ok((Value::Null, stripped));
526    }
527
528    if let Some(stripped) = s.strip_prefix("true") {
529        return Ok((Value::Bool(true), stripped));
530    }
531
532    if let Some(stripped) = s.strip_prefix("false") {
533        return Ok((Value::Bool(false), stripped));
534    }
535
536    if s.starts_with('"') {
537        return parse_string(s);
538    }
539
540    if s.starts_with('[') {
541        return parse_array(s);
542    }
543
544    if s.starts_with('{') {
545        return parse_object(s);
546    }
547
548    if s.starts_with('-') || s.chars().next().map(|c| c.is_ascii_digit()).unwrap_or(false) {
549        return parse_number(s);
550    }
551
552    Err(ValidationErrorKind::InvalidFormat {
553        field: "json".to_string(),
554        expected: format!("valid JSON character, got '{}'", s.chars().next().unwrap_or(' ')),
555    }
556    .into())
557}
558
559fn parse_number(s: &str) -> Result<(Value, &str), WaeError> {
560    let mut i = 0;
561    let mut has_dot = false;
562    let mut has_exp = false;
563
564    if s.starts_with('-') {
565        i += 1;
566    }
567
568    while i < s.len() {
569        let c = s.chars().nth(i).unwrap();
570        if c.is_ascii_digit() {
571            i += 1;
572        }
573        else if c == '.' && !has_dot && !has_exp {
574            has_dot = true;
575            i += 1;
576        }
577        else if (c == 'e' || c == 'E') && !has_exp {
578            has_exp = true;
579            i += 1;
580            if i < s.len() && (s.chars().nth(i).unwrap() == '+' || s.chars().nth(i).unwrap() == '-') {
581                i += 1;
582            }
583        }
584        else {
585            break;
586        }
587    }
588
589    let num_str = &s[..i];
590    if has_dot || has_exp {
591        let v: f64 = num_str.parse().map_err(|e| {
592            WaeError::from(ValidationErrorKind::InvalidFormat {
593                field: "number".to_string(),
594                expected: format!("valid float: {}", e),
595            })
596        })?;
597        Ok((Value::Float(v), &s[i..]))
598    }
599    else {
600        let v: i64 = num_str.parse().map_err(|e| {
601            WaeError::from(ValidationErrorKind::InvalidFormat {
602                field: "number".to_string(),
603                expected: format!("valid integer: {}", e),
604            })
605        })?;
606        Ok((Value::Integer(v), &s[i..]))
607    }
608}
609
610fn parse_string(s: &str) -> Result<(Value, &str), WaeError> {
611    if !s.starts_with('"') {
612        return Err(ValidationErrorKind::InvalidFormat { field: "string".to_string(), expected: "'\"'".to_string() }.into());
613    }
614
615    let mut result = String::new();
616    let mut i = 1;
617    let chars: Vec<char> = s.chars().collect();
618
619    while i < chars.len() {
620        let c = chars[i];
621        if c == '"' {
622            return Ok((Value::String(result), &s[i + 1..]));
623        }
624        if c == '\\' {
625            i += 1;
626            if i >= chars.len() {
627                return Err(ValidationErrorKind::CustomValidation {
628                    field: "string".to_string(),
629                    message: "Unexpected end in escape".to_string(),
630                }
631                .into());
632            }
633            let escaped = chars[i];
634            match escaped {
635                'n' => result.push('\n'),
636                'r' => result.push('\r'),
637                't' => result.push('\t'),
638                '\\' => result.push('\\'),
639                '"' => result.push('"'),
640                '/' => result.push('/'),
641                'u' => {
642                    if i + 4 >= chars.len() {
643                        return Err(ValidationErrorKind::CustomValidation {
644                            field: "string".to_string(),
645                            message: "Invalid unicode escape".to_string(),
646                        }
647                        .into());
648                    }
649                    let hex: String = chars[i + 1..i + 5].iter().collect();
650                    let code = u16::from_str_radix(&hex, 16).map_err(|e| {
651                        WaeError::from(ValidationErrorKind::CustomValidation {
652                            field: "string".to_string(),
653                            message: format!("Invalid unicode: {}", e),
654                        })
655                    })?;
656                    if let Some(c) = char::from_u32(code as u32) {
657                        result.push(c);
658                    }
659                    i += 4;
660                }
661                _ => result.push(escaped),
662            }
663        }
664        else {
665            result.push(c);
666        }
667        i += 1;
668    }
669
670    Err(ValidationErrorKind::CustomValidation { field: "string".to_string(), message: "Unterminated string".to_string() }
671        .into())
672}
673
674fn parse_array(s: &str) -> Result<(Value, &str), WaeError> {
675    if !s.starts_with('[') {
676        return Err(ValidationErrorKind::InvalidFormat { field: "array".to_string(), expected: "'['".to_string() }.into());
677    }
678
679    let mut result = Vec::new();
680    let mut s = &s[1..];
681
682    s = s.trim_start();
683    if let Some(stripped) = s.strip_prefix(']') {
684        return Ok((Value::Array(result), stripped));
685    }
686
687    loop {
688        let (value, remaining) = parse_value(s)?;
689        result.push(value);
690        s = remaining.trim_start();
691
692        if let Some(stripped) = s.strip_prefix(']') {
693            return Ok((Value::Array(result), stripped));
694        }
695
696        if !s.starts_with(',') {
697            return Err(
698                ValidationErrorKind::InvalidFormat { field: "array".to_string(), expected: "',' or ']'".to_string() }.into()
699            );
700        }
701        s = s[1..].trim_start();
702    }
703}
704
705fn parse_object(s: &str) -> Result<(Value, &str), WaeError> {
706    if !s.starts_with('{') {
707        return Err(ValidationErrorKind::InvalidFormat { field: "object".to_string(), expected: "'{'".to_string() }.into());
708    }
709
710    let mut result = HashMap::new();
711    let mut s = &s[1..];
712
713    s = s.trim_start();
714    if let Some(stripped) = s.strip_prefix('}') {
715        return Ok((Value::Object(result), stripped));
716    }
717
718    loop {
719        s = s.trim_start();
720        let (key, remaining) = parse_string(s)?;
721        let key = key
722            .as_str()
723            .ok_or_else(|| {
724                WaeError::from(ValidationErrorKind::CustomValidation {
725                    field: "object_key".to_string(),
726                    message: "Object key must be a string".to_string(),
727                })
728            })?
729            .to_string();
730        s = remaining.trim_start();
731
732        if !s.starts_with(':') {
733            return Err(ValidationErrorKind::InvalidFormat { field: "object".to_string(), expected: "':'".to_string() }.into());
734        }
735        s = s[1..].trim_start();
736
737        let (value, remaining) = parse_value(s)?;
738        result.insert(key, value);
739        s = remaining.trim_start();
740
741        if let Some(stripped) = s.strip_prefix('}') {
742            return Ok((Value::Object(result), stripped));
743        }
744
745        if !s.starts_with(',') {
746            return Err(
747                ValidationErrorKind::InvalidFormat { field: "object".to_string(), expected: "',' or '}'".to_string() }.into()
748            );
749        }
750        s = s[1..].trim_start();
751    }
752}
753
754/// Base64 编码
755fn base64_encode(data: &[u8]) -> String {
756    const ALPHABET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
757
758    let mut result = String::new();
759    let mut i = 0;
760
761    while i < data.len() {
762        let a = data[i] as usize;
763        let b = if i + 1 < data.len() { data[i + 1] as usize } else { 0 };
764        let c = if i + 2 < data.len() { data[i + 2] as usize } else { 0 };
765
766        result.push(ALPHABET[a >> 2] as char);
767        result.push(ALPHABET[((a & 0x03) << 4) | (b >> 4)] as char);
768
769        if i + 1 < data.len() {
770            result.push(ALPHABET[((b & 0x0f) << 2) | (c >> 6)] as char);
771        }
772        else {
773            result.push('=');
774        }
775
776        if i + 2 < data.len() {
777            result.push(ALPHABET[c & 0x3f] as char);
778        }
779        else {
780            result.push('=');
781        }
782
783        i += 3;
784    }
785
786    result
787}