1use std::collections::BTreeMap;
4
5use serde::{Deserialize, Serialize};
6
7use crate::WIRE_SCHEMA_VERSION;
8use crate::context::EffectiveContext;
9use crate::contract::{Assumption, ErrorEstimate, FunctionRef, Trace, Warning};
10use crate::error::EngineError;
11use crate::fingerprint::Receipt;
12use crate::value::Value;
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18pub enum Exactness {
19 Exact,
21 Rounded,
24 Approximate,
27}
28
29impl Exactness {
30 pub fn as_str(self) -> &'static str {
31 match self {
32 Exactness::Exact => "exact",
33 Exactness::Rounded => "rounded",
34 Exactness::Approximate => "approximate",
35 }
36 }
37
38 pub fn combine(self, other: Exactness) -> Exactness {
40 match (self, other) {
41 (Exactness::Approximate, _) | (_, Exactness::Approximate) => Exactness::Approximate,
42 (Exactness::Rounded, _) | (_, Exactness::Rounded) => Exactness::Rounded,
43 _ => Exactness::Exact,
44 }
45 }
46}
47
48#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
51pub struct EngineInfo {
52 pub name: String,
53 pub version: String,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub build: Option<String>,
56 pub modules: BTreeMap<String, String>,
57}
58
59impl EngineInfo {
60 pub fn current() -> EngineInfo {
61 EngineInfo {
62 name: "bicmath".to_string(),
63 version: crate::VERSION.to_string(),
64 build: option_env!("BICMATH_BUILD_ID").map(|s| s.to_string()),
65 modules: BTreeMap::new(),
66 }
67 }
68}
69
70#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
72pub struct ResultEnvelope {
73 pub schema_version: u32,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub function: Option<FunctionRef>,
76 pub engine: EngineInfo,
77 pub result: Value,
78 pub exactness: Exactness,
79 pub context: EffectiveContext,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub error_estimate: Option<ErrorEstimate>,
82 #[serde(default, skip_serializing_if = "Vec::is_empty")]
83 pub warnings: Vec<Warning>,
84 #[serde(default, skip_serializing_if = "Vec::is_empty")]
85 pub assumptions: Vec<Assumption>,
86 pub fingerprint: String,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub receipt: Option<Receipt>,
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub trace: Option<Trace>,
91}
92
93impl ResultEnvelope {
94 pub fn new(
95 function: Option<FunctionRef>,
96 engine: EngineInfo,
97 result: Value,
98 exactness: Exactness,
99 context: EffectiveContext,
100 fingerprint: String,
101 ) -> ResultEnvelope {
102 ResultEnvelope {
103 schema_version: WIRE_SCHEMA_VERSION,
104 function,
105 engine,
106 result,
107 exactness,
108 context,
109 error_estimate: None,
110 warnings: Vec::new(),
111 assumptions: Vec::new(),
112 fingerprint,
113 receipt: None,
114 trace: None,
115 }
116 }
117}
118
119#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
121pub struct ErrorResponse {
122 pub schema_version: u32,
123 pub engine: EngineInfo,
124 pub error: EngineError,
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub fingerprint: Option<String>,
127}
128
129impl ErrorResponse {
130 pub fn new(engine: EngineInfo, error: EngineError) -> ErrorResponse {
131 ErrorResponse {
132 schema_version: WIRE_SCHEMA_VERSION,
133 engine,
134 error,
135 fingerprint: None,
136 }
137 }
138}