1use crate::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(WaeError::parse_error("json", format!("Unexpected characters after JSON: {}", remaining)));
505 }
506 Ok(value)
507}
508
509fn parse_value(s: &str) -> Result<(Value, &str), WaeError> {
510 let s = s.trim_start();
511
512 if s.is_empty() {
513 return Err(WaeError::parse_error("json", "Unexpected end of input"));
514 }
515
516 if let Some(stripped) = s.strip_prefix("null") {
517 return Ok((Value::Null, stripped));
518 }
519
520 if let Some(stripped) = s.strip_prefix("true") {
521 return Ok((Value::Bool(true), stripped));
522 }
523
524 if let Some(stripped) = s.strip_prefix("false") {
525 return Ok((Value::Bool(false), stripped));
526 }
527
528 if s.starts_with('"') {
529 return parse_string(s);
530 }
531
532 if s.starts_with('[') {
533 return parse_array(s);
534 }
535
536 if s.starts_with('{') {
537 return parse_object(s);
538 }
539
540 if s.starts_with('-') || s.chars().next().map(|c| c.is_ascii_digit()).unwrap_or(false) {
541 return parse_number(s);
542 }
543
544 Err(WaeError::parse_error("json", format!("valid JSON character, got '{}'", s.chars().next().unwrap_or(' '))))
545}
546
547fn parse_number(s: &str) -> Result<(Value, &str), WaeError> {
548 let mut i = 0;
549 let mut has_dot = false;
550 let mut has_exp = false;
551
552 if s.starts_with('-') {
553 i += 1;
554 }
555
556 while i < s.len() {
557 let c = s.chars().nth(i).unwrap();
558 if c.is_ascii_digit() {
559 i += 1;
560 }
561 else if c == '.' && !has_dot && !has_exp {
562 has_dot = true;
563 i += 1;
564 }
565 else if (c == 'e' || c == 'E') && !has_exp {
566 has_exp = true;
567 i += 1;
568 if i < s.len() && (s.chars().nth(i).unwrap() == '+' || s.chars().nth(i).unwrap() == '-') {
569 i += 1;
570 }
571 }
572 else {
573 break;
574 }
575 }
576
577 let num_str = &s[..i];
578 if has_dot || has_exp {
579 let v: f64 = num_str.parse().map_err(|e| WaeError::parse_error("number", format!("valid float: {}", e)))?;
580 Ok((Value::Float(v), &s[i..]))
581 }
582 else {
583 let v: i64 = num_str.parse().map_err(|e| WaeError::parse_error("number", format!("valid integer: {}", e)))?;
584 Ok((Value::Integer(v), &s[i..]))
585 }
586}
587
588fn parse_string(s: &str) -> Result<(Value, &str), WaeError> {
589 if !s.starts_with('"') {
590 return Err(WaeError::parse_error("string", "expected '\"'"));
591 }
592
593 let mut result = String::new();
594 let mut i = 1;
595 let chars: Vec<char> = s.chars().collect();
596
597 while i < chars.len() {
598 let c = chars[i];
599 if c == '"' {
600 return Ok((Value::String(result), &s[i + 1..]));
601 }
602 if c == '\\' {
603 i += 1;
604 if i >= chars.len() {
605 return Err(WaeError::parse_error("string", "Unexpected end in escape"));
606 }
607 let escaped = chars[i];
608 match escaped {
609 'n' => result.push('\n'),
610 'r' => result.push('\r'),
611 't' => result.push('\t'),
612 '\\' => result.push('\\'),
613 '"' => result.push('"'),
614 '/' => result.push('/'),
615 'u' => {
616 if i + 4 >= chars.len() {
617 return Err(WaeError::parse_error("string", "Invalid unicode escape"));
618 }
619 let hex: String = chars[i + 1..i + 5].iter().collect();
620 let code = u16::from_str_radix(&hex, 16)
621 .map_err(|e| WaeError::parse_error("string", format!("Invalid unicode: {}", e)))?;
622 if let Some(c) = char::from_u32(code as u32) {
623 result.push(c);
624 }
625 i += 4;
626 }
627 _ => result.push(escaped),
628 }
629 }
630 else {
631 result.push(c);
632 }
633 i += 1;
634 }
635
636 Err(WaeError::parse_error("string", "Unterminated string"))
637}
638
639fn parse_array(s: &str) -> Result<(Value, &str), WaeError> {
640 if !s.starts_with('[') {
641 return Err(WaeError::parse_error("array", "expected '['"));
642 }
643
644 let mut result = Vec::new();
645 let mut s = &s[1..];
646
647 s = s.trim_start();
648 if let Some(stripped) = s.strip_prefix(']') {
649 return Ok((Value::Array(result), stripped));
650 }
651
652 loop {
653 let (value, remaining) = parse_value(s)?;
654 result.push(value);
655 s = remaining.trim_start();
656
657 if let Some(stripped) = s.strip_prefix(']') {
658 return Ok((Value::Array(result), stripped));
659 }
660
661 if !s.starts_with(',') {
662 return Err(WaeError::parse_error("array", "expected ',' or ']'"));
663 }
664 s = s[1..].trim_start();
665 }
666}
667
668fn parse_object(s: &str) -> Result<(Value, &str), WaeError> {
669 if !s.starts_with('{') {
670 return Err(WaeError::parse_error("object", "expected '{'"));
671 }
672
673 let mut result = HashMap::new();
674 let mut s = &s[1..];
675
676 s = s.trim_start();
677 if let Some(stripped) = s.strip_prefix('}') {
678 return Ok((Value::Object(result), stripped));
679 }
680
681 loop {
682 s = s.trim_start();
683 let (key, remaining) = parse_string(s)?;
684 let key = key.as_str().ok_or_else(|| WaeError::parse_error("object_key", "Object key must be a string"))?.to_string();
685 s = remaining.trim_start();
686
687 if !s.starts_with(':') {
688 return Err(WaeError::parse_error("object", "expected ':'"));
689 }
690 s = s[1..].trim_start();
691
692 let (value, remaining) = parse_value(s)?;
693 result.insert(key, value);
694 s = remaining.trim_start();
695
696 if let Some(stripped) = s.strip_prefix('}') {
697 return Ok((Value::Object(result), stripped));
698 }
699
700 if !s.starts_with(',') {
701 return Err(WaeError::parse_error("object", "expected ',' or '}'"));
702 }
703 s = s[1..].trim_start();
704 }
705}
706
707fn base64_encode(data: &[u8]) -> String {
709 const ALPHABET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
710
711 let mut result = String::new();
712 let mut i = 0;
713
714 while i < data.len() {
715 let a = data[i] as usize;
716 let b = if i + 1 < data.len() { data[i + 1] as usize } else { 0 };
717 let c = if i + 2 < data.len() { data[i + 2] as usize } else { 0 };
718
719 result.push(ALPHABET[a >> 2] as char);
720 result.push(ALPHABET[((a & 0x03) << 4) | (b >> 4)] as char);
721
722 if i + 1 < data.len() {
723 result.push(ALPHABET[((b & 0x0f) << 2) | (c >> 6)] as char);
724 }
725 else {
726 result.push('=');
727 }
728
729 if i + 2 < data.len() {
730 result.push(ALPHABET[c & 0x3f] as char);
731 }
732 else {
733 result.push('=');
734 }
735
736 i += 3;
737 }
738
739 result
740}