1use crate::{ValidationErrorKind, WaeError};
4use serde::{Deserialize, Serialize};
5use std::{collections::HashMap, fmt};
6
7#[derive(Debug, Clone, Default, Serialize, Deserialize)]
9pub struct BillingDimensions {
10 pub input_text: u64,
12 pub output_text: u64,
14 pub input_pixels: u64,
16 pub output_pixels: u64,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct TextCost {
23 pub per_million: crate::Decimal,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct ImageCost {
30 pub per_million: crate::Decimal,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct BillingCostConfig {
37 pub input_text: TextCost,
39 pub output_text: TextCost,
41 pub input_pixels: ImageCost,
43 pub output_pixels: ImageCost,
45}
46
47impl BillingCostConfig {
48 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#[derive(Debug, Clone, PartialEq)]
80pub enum Value {
81 Null,
83 Bool(bool),
85 Integer(i64),
87 Float(f64),
89 String(String),
91 Bytes(Vec<u8>),
93 Array(Vec<Value>),
95 Object(HashMap<String, Value>),
97}
98
99impl Value {
100 pub fn null() -> Self {
102 Value::Null
103 }
104
105 pub fn bool(v: bool) -> Self {
107 Value::Bool(v)
108 }
109
110 pub fn integer(v: i64) -> Self {
112 Value::Integer(v)
113 }
114
115 pub fn float(v: f64) -> Self {
117 Value::Float(v)
118 }
119
120 pub fn string(v: impl Into<String>) -> Self {
122 Value::String(v.into())
123 }
124
125 pub fn bytes(v: Vec<u8>) -> Self {
127 Value::Bytes(v)
128 }
129
130 pub fn array(v: Vec<Value>) -> Self {
132 Value::Array(v)
133 }
134
135 pub fn object(v: HashMap<String, Value>) -> Self {
137 Value::Object(v)
138 }
139
140 pub fn is_null(&self) -> bool {
142 matches!(self, Value::Null)
143 }
144
145 pub fn is_bool(&self) -> bool {
147 matches!(self, Value::Bool(_))
148 }
149
150 pub fn is_integer(&self) -> bool {
152 matches!(self, Value::Integer(_))
153 }
154
155 pub fn is_float(&self) -> bool {
157 matches!(self, Value::Float(_))
158 }
159
160 pub fn is_number(&self) -> bool {
162 matches!(self, Value::Integer(_) | Value::Float(_))
163 }
164
165 pub fn is_string(&self) -> bool {
167 matches!(self, Value::String(_))
168 }
169
170 pub fn is_array(&self) -> bool {
172 matches!(self, Value::Array(_))
173 }
174
175 pub fn is_object(&self) -> bool {
177 matches!(self, Value::Object(_))
178 }
179
180 pub fn as_bool(&self) -> Option<bool> {
182 match self {
183 Value::Bool(v) => Some(*v),
184 _ => None,
185 }
186 }
187
188 pub fn as_integer(&self) -> Option<i64> {
190 match self {
191 Value::Integer(v) => Some(*v),
192 _ => None,
193 }
194 }
195
196 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 pub fn as_str(&self) -> Option<&str> {
207 match self {
208 Value::String(v) => Some(v),
209 _ => None,
210 }
211 }
212
213 pub fn as_array(&self) -> Option<&Vec<Value>> {
215 match self {
216 Value::Array(v) => Some(v),
217 _ => None,
218 }
219 }
220
221 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 pub fn as_object(&self) -> Option<&HashMap<String, Value>> {
231 match self {
232 Value::Object(v) => Some(v),
233 _ => None,
234 }
235 }
236
237 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 pub fn get(&self, key: &str) -> Option<&Value> {
247 match self {
248 Value::Object(map) => map.get(key),
249 _ => None,
250 }
251 }
252
253 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 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 pub fn from_json_str(s: &str) -> Result<Value, WaeError> {
286 parse_json_value(s.trim())
287 }
288
289 pub fn deep_clone(&self) -> Value {
291 self.clone()
292 }
293
294 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
500fn 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
754fn 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}