Skip to main content

gemini_rs/
types.rs

1//! Contains every type used in the library
2
3use std::collections::BTreeMap;
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8/// The producer of the content
9#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
10#[serde(rename_all = "lowercase")]
11pub enum Role {
12    User,
13    Model,
14}
15
16#[derive(Debug, Deserialize)]
17#[serde(untagged)]
18pub enum ApiResponse<T> {
19    Ok(T),
20    Err(ApiError),
21}
22
23#[derive(Debug, Deserialize)]
24pub struct ApiError {
25    pub error: ErrorDetail,
26}
27
28#[derive(Debug, Deserialize)]
29pub struct ErrorDetail {
30    pub code: u16,
31    pub message: String,
32    pub status: Status,
33    #[serde(default)]
34    pub details: Vec<ErrorInfo>,
35}
36
37#[derive(Debug, Deserialize)]
38pub struct ErrorInfo {
39    #[serde(rename = "@type")]
40    pub r#type: String,
41    #[serde(default)]
42    pub reason: Option<String>,
43    #[serde(default)]
44    pub domain: Option<String>,
45    #[serde(default)]
46    pub metadata: Option<BTreeMap<String, String>>,
47}
48
49/// Common backend error codes you may encounter
50///
51/// Use the [API Reference](https://ai.google.dev/gemini-api/docs/troubleshooting#error-codes) for
52/// troubleshooting steps
53#[derive(Debug, Deserialize)]
54#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
55pub enum Status {
56    /// The request body is malformed
57    InvalidArgument,
58    /// Gemini API free tier is not available in your country. Please enable billing on your project in Google AI Studio.
59    FailedPrecondition,
60    /// Your API key doesn't have the required permissions.
61    PermissionDenied,
62    /// The requested resource wasn't found.
63    NotFound,
64    /// You've exceeded the rate limit.
65    ResourceExhausted,
66    /// An unexpected error occurred on Google's side.
67    Internal,
68    /// The service may be temporarily overloaded or down.
69    Unavailable,
70    /// The service is unable to finish processing within the deadline.
71    DeadlineExceeded,
72}
73
74/// Response from [crate::Client::models] containing a paginated list of Models
75///
76/// [API Reference](https://ai.google.dev/api/models#response-body_1)
77#[derive(Deserialize, Debug)]
78#[serde(rename_all = "camelCase")]
79pub struct Models {
80    pub models: Vec<Model>,
81    pub next_page_token: Option<String>,
82}
83
84/// Information about a Generative Language Model
85///
86/// [API Reference](https://ai.google.dev/api/models#Model)
87#[derive(Debug, Default, Deserialize)]
88#[serde(rename_all = "camelCase")]
89pub struct Model {
90    pub name: String,
91    pub version: String,
92    pub display_name: String,
93    pub description: String,
94    pub input_token_limit: i32,
95    pub output_token_limit: i32,
96    pub supported_generation_methods: Vec<String>,
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub temperature: Option<f32>,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub top_p: Option<f32>,
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub top_k: Option<i32>,
103}
104
105/// Response from the model supporting multiple candidate responses
106///
107/// [API Reference](https://ai.google.dev/api/generate-content#generatecontentresponse)
108#[derive(Debug, Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct Response {
111    pub candidates: Vec<Candidate>,
112    pub prompt_feedback: Option<PromptFeedback>,
113    pub usage_metadata: Option<UsageMetadata>,
114}
115
116impl std::fmt::Display for Response {
117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118        f.write_str(
119            self.candidates[0].content.parts[0]
120                .text
121                .as_deref()
122                .unwrap_or_default(),
123        )
124    }
125}
126
127/// Metadata on the generation request's token usage
128///
129/// [API Reference](https://ai.google.dev/api/generate-content#UsageMetadata)
130#[derive(Debug, Deserialize)]
131#[serde(rename_all = "camelCase")]
132pub struct UsageMetadata {
133    pub prompt_token_count: u64,
134    pub candidates_token_count: u64,
135}
136
137/// A response candidate generated from the model
138///
139/// [API Reference](https://ai.google.dev/api/generate-content#candidate)
140#[derive(Debug, Deserialize)]
141#[serde(rename_all = "camelCase")]
142pub struct Candidate {
143    pub content: Content,
144    pub finish_reason: Option<FinishReason>,
145    pub index: Option<i32>,
146    #[serde(default)]
147    pub safety_ratings: Vec<SafetyRating>,
148}
149
150/// A set of the feedback metadata the prompt specified in [GenerateContentRequest.content].
151///
152/// [API Reference](https://ai.google.dev/api/generate-content#PromptFeedback)
153#[derive(Debug, Deserialize)]
154pub struct PromptFeedback {
155    #[serde(rename = "safetyRatings")]
156    pub safety_ratings: Vec<SafetyRating>,
157}
158
159/// Safety rating for a piece of content
160///
161/// The safety rating contains the category of harm and the harm probability level in that category for a piece of content.
162/// Content is classified for safety across a number of harm categories and the probability of the harm classification is included here.
163///
164/// [API Reference](https://ai.google.dev/api/generate-content#safetyrating)
165#[derive(Debug, Deserialize)]
166pub struct SafetyRating {
167    pub category: HarmCategory,
168    pub probability: HarmProbability,
169    #[serde(default)]
170    pub blocked: bool,
171}
172
173#[derive(Debug, Serialize, Deserialize, Clone)]
174pub struct FunctionCall {
175    #[serde(rename = "id", skip_serializing_if = "Option::is_none")]
176    pub id: Option<String>,
177    pub name: String,
178    pub args: Value,
179}
180
181/// The base structured datatype containing multi-part content of a message
182///
183/// [API Reference](https://ai.google.dev/api/caching#Content)
184#[derive(Debug, Deserialize, Serialize, Clone)]
185pub struct Content {
186    pub role: Role,
187    #[serde(default)]
188    pub parts: Vec<Part>,
189}
190
191/// A datatype containing media that is part of a multi-part Content message
192///
193/// [API Reference](https://ai.google.dev/api/caching#Part)
194#[derive(Debug, Default, Deserialize, Serialize, Clone)]
195#[serde(rename_all = "camelCase")]
196pub struct Part {
197    #[serde(skip_serializing_if = "Option::is_none")]
198    pub text: Option<String>,
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub inline_data: Option<InlineData>,
201    #[serde(skip_serializing_if = "Option::is_none")]
202    pub file_data: Option<FileData>,
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub video_metadata: Option<VideoMetadata>,
205    #[serde(skip_serializing_if = "Option::is_none")]
206    pub executable_code: Option<ExecutableCode>,
207    #[serde(skip_serializing_if = "Option::is_none")]
208    pub code_execution_result: Option<CodeExecutionResult>,
209    #[serde(rename = "functionCall", skip_serializing_if = "Option::is_none")]
210    pub function_call: Option<FunctionCall>,
211}
212
213impl Part {
214    pub fn text(text: &str) -> Self {
215        Self {
216            text: Some(text.into()),
217            ..Default::default()
218        }
219    }
220    pub fn inline_data(mime_type: &str, data: &str) -> Self {
221        Self {
222            inline_data: Some(InlineData {
223                mime_type: mime_type.into(),
224                data: data.into(),
225            }),
226            ..Default::default()
227        }
228    }
229}
230
231/// Metadata for a video File
232///
233/// [API Reference](https://ai.google.dev/api/files#VideoFileMetadata)
234#[derive(Debug, Deserialize, Serialize, Clone)]
235#[serde(rename_all = "camelCase")]
236pub struct VideoMetadata {
237    pub start_offset: StartOffset,
238    pub end_offset: EndOffset,
239}
240
241#[derive(Debug, Deserialize, Serialize, Clone)]
242pub struct EndOffset {
243    pub seconds: i32,
244    pub nanos: i32,
245}
246
247#[derive(Debug, Deserialize, Serialize, Clone)]
248pub struct StartOffset {
249    pub seconds: i32,
250    pub nanos: i32,
251}
252
253/// URI based data
254///
255/// [API Reference](https://ai.google.dev/api/caching#FileData)
256#[derive(Debug, Deserialize, Serialize, Clone)]
257pub struct FileData {
258    pub mime_type: String,
259    pub file_uri: String,
260}
261
262/// Inline media bytes (stored as a base64 string for some reason) //todo
263///
264/// [API Reference](https://ai.google.dev/api/caching#Blob)
265#[derive(Debug, Deserialize, Serialize, Clone)]
266#[serde(rename_all = "camelCase")]
267pub struct InlineData {
268    pub mime_type: String,
269    pub data: String,
270}
271
272/// Defines the reason why the model stopped generating tokens
273///
274/// [API Reference](https://ai.google.dev/api/generate-content#FinishReason)
275#[derive(Debug, Serialize, Deserialize)]
276#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
277pub enum FinishReason {
278    /// Default value. This value is unused.
279    FinishReasonUnspecified,
280    /// Natural stop point of the model or provided stop sequence
281    Stop,
282    /// The maximum number of tokens as specified in the request was reached
283    MaxTokens,
284    /// The response candidate content was flagged for safety reasons
285    Safety,
286    /// The response candidate content was flagged for recitation reasons
287    Recitation,
288    /// The response candidate content was flagged for using an unsupported language
289    Language,
290    /// Unknown reason
291    Other,
292    /// Token generation stopped because the content contains forbidden terms
293    Blocklist,
294    /// Token generation stopped for potentially containing prohibited content
295    ProhibitedContent,
296    /// Token generation stopped because the content potentially contains Sensitive Personally Identifiable Information (SPII)
297    Spii,
298    /// The function call generated by the model is invalid
299    MalformedFunctionCall,
300    /// Token generation stopped because generated images contain safety violations
301    ImageSafety,
302}
303
304/// The category of a rating
305///
306/// These categories cover various kinds of harms that developers may wish to adjust
307///
308/// [API Reference](https://ai.google.dev/api/generate-content#harmcategory)
309#[derive(Debug, Serialize, Deserialize, Clone)]
310#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
311pub enum HarmCategory {
312    /// Category is unspecified
313    HarmCategoryUnspecified,
314    /// PaLM - Negative or harmful comments targeting identity and/or protected attribute
315    HarmCategoryDerogatory,
316    /// PaLM - Content that is rude, disrespectful, or profane
317    HarmCategoryToxicity,
318    /// PaLM - Describes scenarios depicting violence against an individual or group, or general descriptions of gore
319    HarmCategoryViolence,
320    /// PaLM - Describes scenarios depicting violence against an individual or group, or general descriptions of gore
321    HarmCategorySexual,
322    /// PaLM - Promotes unchecked medical advice
323    HarmCategoryMedical,
324    /// PaLM - Dangerous content that promotes, facilitates, or encourages harmful acts
325    HarmCategoryDangerous,
326    /// Gemini - Harassment content
327    HarmCategoryHarassment,
328    /// Gemini - Hate speech and content
329    HarmCategoryHateSpeech,
330    /// Gemini - Sexually explicit content
331    HarmCategorySexuallyExplicit,
332    /// Gemini - Dangerous content
333    HarmCategoryDangerousContent,
334    /// Gemini - Content that may be used to harm civic integrity
335    HarmCategoryCivicIntegrity,
336}
337
338/// Block at and beyond a specified harm probability
339///
340/// [API Reference](https://ai.google.dev/api/generate-content#HarmBlockThreshold)
341#[derive(Debug, Deserialize, Serialize, Clone)]
342#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
343pub enum HarmBlockThreshold {
344    /// Threshold is unspecified
345    HarmBlockThresholdUnspecified,
346    /// Content with [HarmProbability::Negligible] will be allowed
347    BlockLowAndAbove,
348    /// Content with [HarmProbability::Negligible] and [HarmProbability::Low] will be allowed
349    BlockMedAndAbove,
350    /// Content with [HarmProbability::Negligible], [HarmProbability::Low], and
351    /// [HarmProbability::Medium] will be allowed
352    BlockOnlyHigh,
353    /// All content will be allowed
354    BlockNone,
355    /// Turn off the safety filter
356    OFF,
357}
358
359/// The probability that a piece of content is harmful
360///
361/// The classification system gives the probability of the content being unsafe. This does not
362/// indicate the severity of harm for a piece of content.
363///
364/// [API Reference](https://ai.google.dev/api/generate-content#HarmProbability)
365#[derive(Debug, Deserialize, Serialize)]
366#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
367pub enum HarmProbability {
368    /// Probability is unspecified
369    HarmProbabilityUnspecified,
370    /// Content has a negligible chance of being unsafe
371    Negligible,
372    /// Content has a low chance of being unsafe
373    Low,
374    /// Content has a medium chance of being unsafe
375    Medium,
376    /// Content has a high chance of being unsafe
377    High,
378}
379
380/// GoogleSearch tool type.
381///
382/// Tool to support Google Search in Model. Powered by Google.
383///
384/// [API Reference](https://ai.google.dev/api/caching#GoogleSearch)
385#[derive(Debug, Clone, Deserialize, Serialize)]
386pub struct GoogleSearchTool {}
387
388/// Tool that executes code generated by the model, and automatically returns the result to the model
389///
390/// See also [ExecutableCode] and [CodeExecutionResult] which are only generated when using this tool
391///
392/// [API Reference](https://ai.google.dev/api/caching#CodeExecution)
393#[derive(Debug, Clone, Deserialize, Serialize)]
394pub struct CodeExecutionTool {}
395
396/// Tool details that the model may use to generate response
397///
398/// A `Tool` is a piece of code that enables the system to interact with external systems to perform
399/// an action, or set of actions, outside of knowledge and scope of the model.
400///
401/// [API Reference](https://ai.google.dev/api/caching#Tool)
402#[derive(Debug, Clone, Serialize)]
403pub struct Tools {
404    #[serde(skip_serializing_if = "Option::is_none")]
405    #[serde(rename = "functionDeclarations")]
406    pub function_declarations: Option<Vec<FunctionDeclaration>>,
407    #[serde(skip_serializing_if = "Option::is_none")]
408    pub google_search: Option<GoogleSearchTool>,
409    #[serde(skip_serializing_if = "Option::is_none")]
410    pub code_execution: Option<CodeExecutionTool>,
411}
412
413/// Structured representation of a function declaration
414///
415/// Defined by the OpenAPI 3.03 specification.
416/// `FunctionDeclaration` is a representation of a block of code that can be used in [Tools] by the model and executed by the client.
417///
418/// [API Reference](https://ai.google.dev/api/caching#FunctionDeclaration)
419#[derive(Debug, Clone, Deserialize, Serialize)]
420pub struct FunctionDeclaration {
421    pub name: String,
422    pub description: String,
423    /// Defines the input parameters the function expects
424    ///
425    /// Use the [API Reference](https://ai.google.dev/gemini-api/docs/function-calling#function_declarations)
426    /// to see how to structure the parameters.
427    pub parameters: Value,
428}
429
430/// Request to generate content from the model
431///
432/// [API Reference](https://ai.google.dev/api/generate-content#request-body)
433#[derive(Debug, Default, Clone, Serialize)]
434pub struct GenerateContent {
435    pub contents: Vec<Content>,
436    #[serde(skip_serializing_if = "Vec::is_empty")]
437    pub tools: Vec<Tools>,
438    #[serde(
439        default,
440        rename = "toolConfig",
441        skip_serializing_if = "Option::is_none"
442    )]
443    pub tool_config: Option<ToolConfig>,
444    #[serde(skip_serializing_if = "Vec::is_empty")]
445    #[serde(default, rename = "safetySettings")]
446    pub safety_settings: Vec<SafetySettings>,
447    #[serde(skip_serializing_if = "Option::is_none")]
448    #[serde(default, rename = "system_instruction")]
449    pub system_instruction: Option<SystemInstructionContent>,
450    #[serde(skip_serializing_if = "Option::is_none")]
451    #[serde(default, rename = "generationConfig")]
452    pub generation_config: Option<GenerationConfig>,
453}
454
455/// System instructions are used to provide the model with additional context or instructions
456///
457/// Similar to the [Content] struct, but specifically for system instructions.
458#[derive(Debug, Clone, Deserialize, Serialize)]
459pub struct SystemInstructionContent {
460    #[serde(default)]
461    pub parts: Vec<SystemInstructionPart>,
462}
463
464/// A part of the system instruction content
465#[derive(Debug, Clone, Deserialize, Serialize)]
466#[serde(rename_all = "camelCase")]
467pub struct SystemInstructionPart {
468    #[serde(skip_serializing_if = "Option::is_none")]
469    pub text: Option<String>,
470}
471
472/// Configuration options for model generation and outputs.
473///
474/// Not all parameters are configurable for every model.
475///
476/// [API Reference](https://ai.google.dev/api/generate-content#v1beta.GenerationConfig)
477#[derive(Debug, Deserialize, Serialize, Default, Clone)]
478#[serde(rename_all = "camelCase")]
479pub struct GenerationConfig {
480    pub temperature: Option<f32>,
481    pub top_p: Option<f32>,
482    pub top_k: Option<i32>,
483    pub candidate_count: Option<i32>,
484    pub max_output_tokens: Option<i32>,
485    pub stop_sequences: Option<Vec<String>>,
486    pub response_mime_type: Option<String>,
487    pub response_schema: Option<Schema>,
488    #[serde(rename = "thinkingConfig", skip_serializing_if = "Option::is_none")]
489    pub thinking_config: Option<ThinkingConfig>,
490}
491
492/// Config for thinking features
493///
494/// [API Reference](https://ai.google.dev/api/generate-content#ThinkingConfig)
495#[derive(Debug, Default, Serialize, Deserialize, Clone)]
496#[serde(rename_all = "camelCase")]
497pub struct ThinkingConfig {
498    #[serde(rename = "thinkingBudget", skip_serializing_if = "Option::is_none")]
499    pub thinking_budget: Option<u16>, // 0~24576
500    #[serde(rename = "includeThoughts", skip_serializing_if = "Option::is_none")]
501    pub include_thoughts: Option<bool>,
502}
503
504/// Safety setting, affecting the safety-blocking behavior
505///
506/// Passing a safety setting for a category changes the allowed probability that content is blocked.
507///
508/// [API Reference](https://ai.google.dev/api/generate-content#safetysetting)
509#[derive(Debug, Deserialize, Serialize, Clone)]
510pub struct SafetySettings {
511    pub category: HarmCategory,
512    pub threshold: HarmBlockThreshold,
513}
514
515/// The Schema object allows the definition of input and output data types.
516///
517/// These types can be objects, but also primitives and arrays.
518/// Represents a select subset of an [OpenAPI 3.0 schema
519/// object](https://spec.openapis.org/oas/v3.0.3#schema).
520///
521/// [API Reference](https://ai.google.dev/api/caching#Schema)
522#[derive(Debug, Serialize, Deserialize, Clone, Default)]
523#[serde(rename_all = "camelCase")]
524pub struct Schema {
525    #[serde(rename = "type")]
526    pub schema_type: Option<Type>,
527    pub format: Option<String>,
528    pub title: Option<String>,
529    pub description: Option<String>,
530    pub nullable: Option<bool>,
531    #[serde(rename = "enum")]
532    pub enum_values: Option<Vec<String>>,
533    #[serde(rename = "maxItems")]
534    pub max_items: Option<String>,
535    #[serde(rename = "minItems")]
536    pub min_items: Option<String>,
537    pub properties: Option<BTreeMap<String, Schema>>,
538    pub required: Option<Vec<String>>,
539    #[serde(rename = "propertyOrdering")]
540    pub property_ordering: Option<Vec<String>>,
541    pub items: Option<Box<Schema>>,
542}
543
544/// The Tool configuration containing parameters for specifying [Tools] use in the request
545///
546/// [API Reference](https://ai.google.dev/api/caching#ToolConfig)
547#[derive(Debug, Clone, Deserialize, Serialize)]
548#[serde(rename_all = "camelCase")]
549pub struct ToolConfig {
550    #[serde(skip_serializing_if = "Option::is_none")]
551    pub function_calling_config: Option<FunctionCallingConfig>,
552}
553
554/// Configuration for specifying function calling behavior
555///
556/// [API Reference](https://ai.google.dev/api/caching#FunctionCallingConfig)
557#[derive(Debug, Clone, Deserialize, Serialize)]
558#[serde(rename_all = "camelCase")]
559pub struct FunctionCallingConfig {
560    #[serde(skip_serializing_if = "Option::is_none")]
561    pub mode: Option<FunctionCallingMode>,
562    #[serde(skip_serializing_if = "Option::is_none")]
563    pub allowed_function_names: Option<Vec<String>>,
564}
565
566/// Defines the execution behavior for function calling by defining the execution mode
567///
568/// [API Reference](https://ai.google.dev/api/caching#Mode_1)
569#[derive(Debug, Clone, Deserialize, Serialize)]
570#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
571pub enum FunctionCallingMode {
572    /// Unspecified function calling mode. This value should not be used.
573    ModeUnspecified,
574    /// Default model behavior, model decides to predict either a function call or a natural language response.
575    Auto,
576    /// Model is constrained to always predicting a function call only. If "allowedFunctionNames" are set, the predicted function call will be limited to any one of "allowedFunctionNames", else the predicted function call will be any one of the provided "functionDeclarations".
577    Any,
578    /// Model will not predict any function call. Model behavior is same as when not passing any function declarations.
579    None,
580    /// Model decides to predict either a function call or a natural language response, but will validate function calls with constrained decoding.
581    Validated,
582}
583
584/// Code generated by the model that is meant to be executed, and the result returned to the model
585///
586/// Only generated when using the [CodeExecutionTool] tool, in which the code will be automatically executed, and a corresponding [CodeExecutionResult] will also be generated.
587#[derive(Debug, Deserialize, Serialize, Clone)]
588pub struct ExecutableCode {
589    #[serde(rename = "language")]
590    pub language: ProgrammingLanguage,
591    #[serde(rename = "code")]
592    pub code: String,
593}
594
595/// Supported programming languages for the generated code
596///
597/// [API Reference](https://ai.google.dev/api/caching#Language)
598#[derive(Debug, Deserialize, Serialize, Clone)]
599#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
600pub enum ProgrammingLanguage {
601    /// Unspecified language. This value should not be used.
602    LanguageUnspecified,
603    /// Python >= 3.10, with numpy and simpy available.
604    Python,
605}
606
607/// Enumeration of possible outcomes of the [CodeExecutionTool]
608///
609/// [API Reference](https://ai.google.dev/api/caching#Outcome)
610#[derive(Debug, Deserialize, Serialize, Clone)]
611#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
612pub enum Outcome {
613    /// Unspecified status. This value should not be used.
614    OutcomeUnspecified,
615    /// Code execution completed successfully.
616    OutcomeOk,
617    /// Code execution finished but with a failure. stderr should contain the reason.
618    OutcomeError,
619    /// Code execution ran for too long, and was cancelled. There may or may not be a partial output present.
620    OutcomeDeadlineExceeded,
621}
622
623/// The result output from a [FunctionCall]
624///
625/// [API Reference](https://ai.google.dev/api/caching#FunctionResponse)
626#[derive(Debug, Deserialize, Serialize, Clone)]
627pub struct FunctionResponse {
628    #[serde(skip_serializing_if = "Option::is_none")]
629    pub id: Option<String>,
630    pub name: String,
631    #[serde(skip_serializing_if = "Option::is_none")]
632    //Optional. The function parameters and values in JSON object format.
633    pub args: Option<Value>,
634}
635
636/// Result of executing the [ExecutableCode]
637///
638/// [API Reference](https://ai.google.dev/api/caching#CodeExecutionResult)
639#[derive(Debug, Deserialize, Serialize, Clone)]
640pub struct CodeExecutionResult {
641    pub outcome: Outcome,
642    #[serde(skip_serializing_if = "Option::is_none")]
643    pub output: Option<String>,
644}
645
646/// Definitions of the types of data that can be used in [Schema]
647///
648/// Copied from [serde_json](https://docs.rs/serde_json/1.0.140/serde_json/value/enum.Value.html)
649#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
650#[serde(rename_all = "lowercase")]
651pub enum Type {
652    Object,
653    Array,
654    String,
655    Integer,
656    Number,
657    Boolean,
658}