cleanup schema function calls
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
821aa8eae6
commit
9fa3026a08
|
@ -345,8 +345,8 @@ impl std::str::FromStr for GroupFilter {
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.split_once(":") {
|
match s.split_once(":") {
|
||||||
Some(("group", value)) => parse_simple_value(value, &BACKUP_GROUP_SCHEMA).map(|_| GroupFilter::Group(value.to_string())),
|
Some(("group", value)) => BACKUP_GROUP_SCHEMA.parse_simple_value(value).map(|_| GroupFilter::Group(value.to_string())),
|
||||||
Some(("type", value)) => parse_simple_value(value, &BACKUP_TYPE_SCHEMA).map(|_| GroupFilter::BackupType(value.to_string())),
|
Some(("type", value)) => BACKUP_TYPE_SCHEMA.parse_simple_value(value).map(|_| GroupFilter::BackupType(value.to_string())),
|
||||||
Some(("regex", value)) => Ok(GroupFilter::Regex(Regex::new(value)?)),
|
Some(("regex", value)) => Ok(GroupFilter::Regex(Regex::new(value)?)),
|
||||||
Some((ty, _value)) => Err(format_err!("expected 'group', 'type' or 'regex' prefix, got '{}'", ty)),
|
Some((ty, _value)) => Err(format_err!("expected 'group', 'type' or 'regex' prefix, got '{}'", ty)),
|
||||||
None => Err(format_err!("input doesn't match expected format '<group:GROUP||type:<vm|ct|host>|regex:REGEX>'")),
|
None => Err(format_err!("input doesn't match expected format '<group:GROUP||type:<vm|ct|host>|regex:REGEX>'")),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, Error};
|
||||||
|
|
||||||
use proxmox_schema::{parse_simple_value, ApiStringFormat, Schema, StringSchema};
|
use proxmox_schema::{ApiStringFormat, Schema, StringSchema};
|
||||||
|
|
||||||
use crate::{CHANGER_NAME_SCHEMA, PROXMOX_SAFE_ID_FORMAT};
|
use crate::{CHANGER_NAME_SCHEMA, PROXMOX_SAFE_ID_FORMAT};
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@ impl proxmox_schema::ApiType for MediaLocation {
|
||||||
let location: MediaLocation = text.parse()?;
|
let location: MediaLocation = text.parse()?;
|
||||||
match location {
|
match location {
|
||||||
MediaLocation::Online(ref changer) => {
|
MediaLocation::Online(ref changer) => {
|
||||||
parse_simple_value(changer, &CHANGER_NAME_SCHEMA)?;
|
CHANGER_NAME_SCHEMA.parse_simple_value(changer)?;
|
||||||
}
|
}
|
||||||
MediaLocation::Vault(ref vault) => {
|
MediaLocation::Vault(ref vault) => {
|
||||||
parse_simple_value(vault, &VAULT_NAME_SCHEMA)?;
|
VAULT_NAME_SCHEMA.parse_simple_value(vault)?;
|
||||||
}
|
}
|
||||||
MediaLocation::Offline => { /* OK */ }
|
MediaLocation::Offline => { /* OK */ }
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use endian_trait::Endian;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use proxmox_schema::parse_property_string;
|
|
||||||
use proxmox_uuid::Uuid;
|
use proxmox_uuid::Uuid;
|
||||||
|
|
||||||
use pbs_api_types::{ScsiTapeChanger, SLOT_ARRAY_SCHEMA};
|
use pbs_api_types::{ScsiTapeChanger, SLOT_ARRAY_SCHEMA};
|
||||||
|
@ -313,7 +312,7 @@ impl MtxStatus {
|
||||||
let mut export_slots: HashSet<u64> = HashSet::new();
|
let mut export_slots: HashSet<u64> = HashSet::new();
|
||||||
|
|
||||||
if let Some(slots) = &config.export_slots {
|
if let Some(slots) = &config.export_slots {
|
||||||
let slots: Value = parse_property_string(&slots, &SLOT_ARRAY_SCHEMA)?;
|
let slots: Value = SLOT_ARRAY_SCHEMA.parse_property_string(&slots)?;
|
||||||
export_slots = slots
|
export_slots = slots
|
||||||
.as_array()
|
.as_array()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -26,10 +26,7 @@ use proxmox_router::{
|
||||||
RpcEnvironmentType, UserInformation,
|
RpcEnvironmentType, UserInformation,
|
||||||
};
|
};
|
||||||
use proxmox_router::http_err;
|
use proxmox_router::http_err;
|
||||||
use proxmox_schema::{
|
use proxmox_schema::{ObjectSchemaType, ParameterSchema};
|
||||||
parse_parameter_strings, parse_simple_value, verify_json_object, ObjectSchemaType,
|
|
||||||
ParameterSchema,
|
|
||||||
};
|
|
||||||
|
|
||||||
use proxmox_http::client::RateLimitedStream;
|
use proxmox_http::client::RateLimitedStream;
|
||||||
|
|
||||||
|
@ -330,7 +327,7 @@ fn parse_query_parameters<S: 'static + BuildHasher + Send>(
|
||||||
param_list.push((k.clone(), v.clone()));
|
param_list.push((k.clone(), v.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let params = parse_parameter_strings(¶m_list, param_schema, true)?;
|
let params = param_schema.parse_parameter_strings(¶m_list, true)?;
|
||||||
|
|
||||||
Ok(params)
|
Ok(params)
|
||||||
}
|
}
|
||||||
|
@ -376,10 +373,10 @@ async fn get_request_parameters<S: 'static + BuildHasher + Send>(
|
||||||
let mut params: Value = serde_json::from_str(utf8_data)?;
|
let mut params: Value = serde_json::from_str(utf8_data)?;
|
||||||
for (k, v) in uri_param {
|
for (k, v) in uri_param {
|
||||||
if let Some((_optional, prop_schema)) = param_schema.lookup(&k) {
|
if let Some((_optional, prop_schema)) = param_schema.lookup(&k) {
|
||||||
params[&k] = parse_simple_value(&v, prop_schema)?;
|
params[&k] = prop_schema.parse_simple_value(&v)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verify_json_object(¶ms, ¶m_schema)?;
|
param_schema.verify_json(¶ms)?;
|
||||||
return Ok(params);
|
return Ok(params);
|
||||||
} else {
|
} else {
|
||||||
parse_query_parameters(param_schema, utf8_data, &parts, &uri_param)
|
parse_query_parameters(param_schema, utf8_data, &parts, &uri_param)
|
||||||
|
|
|
@ -8,8 +8,7 @@ use serde_json::json;
|
||||||
|
|
||||||
use proxmox_router::RpcEnvironment;
|
use proxmox_router::RpcEnvironment;
|
||||||
use proxmox_router::cli::{run_cli_command, complete_file_name, CliCommand, CliCommandMap, CliEnvironment};
|
use proxmox_router::cli::{run_cli_command, complete_file_name, CliCommand, CliCommandMap, CliEnvironment};
|
||||||
use proxmox_schema::{api, parse_property_string};
|
use proxmox_schema::{api, ApiStringFormat, ApiType, IntegerSchema, Schema, StringSchema};
|
||||||
use proxmox_schema::{ApiStringFormat, ApiType, IntegerSchema, Schema, StringSchema};
|
|
||||||
|
|
||||||
use proxmox_sys::fs::CreateOptions;
|
use proxmox_sys::fs::CreateOptions;
|
||||||
|
|
||||||
|
@ -262,7 +261,7 @@ pub fn create_rrd(
|
||||||
|
|
||||||
for item in rra.iter() {
|
for item in rra.iter() {
|
||||||
let rra: RRAConfig = serde_json::from_value(
|
let rra: RRAConfig = serde_json::from_value(
|
||||||
parse_property_string(item, &RRAConfig::API_SCHEMA)?
|
RRAConfig::API_SCHEMA.parse_property_string(item)?
|
||||||
)?;
|
)?;
|
||||||
println!("GOT {:?}", rra);
|
println!("GOT {:?}", rra);
|
||||||
rra_list.push(RRA::new(rra.cf, rra.r, rra.n as usize));
|
rra_list.push(RRA::new(rra.cf, rra.r, rra.n as usize));
|
||||||
|
|
|
@ -8,7 +8,7 @@ use proxmox_sys::sortable;
|
||||||
use proxmox_router::{
|
use proxmox_router::{
|
||||||
http_err, list_subdirs_api_method, Router, RpcEnvironment, SubdirMap, Permission,
|
http_err, list_subdirs_api_method, Router, RpcEnvironment, SubdirMap, Permission,
|
||||||
};
|
};
|
||||||
use proxmox_schema::{api, parse_simple_value};
|
use proxmox_schema::api;
|
||||||
|
|
||||||
use proxmox_openid::{OpenIdAuthenticator, OpenIdConfig};
|
use proxmox_openid::{OpenIdAuthenticator, OpenIdConfig};
|
||||||
|
|
||||||
|
@ -158,13 +158,13 @@ pub fn openid_login(
|
||||||
let _lock = open_backup_lockfile(user::USER_CFG_LOCKFILE, None, true)?;
|
let _lock = open_backup_lockfile(user::USER_CFG_LOCKFILE, None, true)?;
|
||||||
|
|
||||||
let firstname = info["given_name"].as_str().map(|n| n.to_string())
|
let firstname = info["given_name"].as_str().map(|n| n.to_string())
|
||||||
.filter(|n| parse_simple_value(n, &FIRST_NAME_SCHEMA).is_ok());
|
.filter(|n| FIRST_NAME_SCHEMA.parse_simple_value(n).is_ok());
|
||||||
|
|
||||||
let lastname = info["family_name"].as_str().map(|n| n.to_string())
|
let lastname = info["family_name"].as_str().map(|n| n.to_string())
|
||||||
.filter(|n| parse_simple_value(n, &LAST_NAME_SCHEMA).is_ok());
|
.filter(|n| LAST_NAME_SCHEMA.parse_simple_value(n).is_ok());
|
||||||
|
|
||||||
let email = info["email"].as_str().map(|n| n.to_string())
|
let email = info["email"].as_str().map(|n| n.to_string())
|
||||||
.filter(|n| parse_simple_value(n, &EMAIL_SCHEMA).is_ok());
|
.filter(|n| EMAIL_SCHEMA.parse_simple_value(n).is_ok());
|
||||||
|
|
||||||
let user = User {
|
let user = User {
|
||||||
userid: user_id.clone(),
|
userid: user_id.clone(),
|
||||||
|
|
|
@ -4,7 +4,7 @@ use serde_json::Value;
|
||||||
use hex::FromHex;
|
use hex::FromHex;
|
||||||
|
|
||||||
use proxmox_router::{Router, RpcEnvironment, Permission};
|
use proxmox_router::{Router, RpcEnvironment, Permission};
|
||||||
use proxmox_schema::{api, parse_property_string};
|
use proxmox_schema::api;
|
||||||
|
|
||||||
use pbs_api_types::{
|
use pbs_api_types::{
|
||||||
Authid, ScsiTapeChanger, ScsiTapeChangerUpdater, LtoTapeDrive,
|
Authid, ScsiTapeChanger, ScsiTapeChangerUpdater, LtoTapeDrive,
|
||||||
|
@ -205,9 +205,7 @@ pub fn update_changer(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(export_slots) = update.export_slots {
|
if let Some(export_slots) = update.export_slots {
|
||||||
let slots: Value = parse_property_string(
|
let slots: Value = SLOT_ARRAY_SCHEMA.parse_property_string(&export_slots)?;
|
||||||
&export_slots, &SLOT_ARRAY_SCHEMA
|
|
||||||
)?;
|
|
||||||
let mut slots: Vec<String> = slots
|
let mut slots: Vec<String> = slots
|
||||||
.as_array()
|
.as_array()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -6,7 +6,7 @@ use ::serde::{Deserialize, Serialize};
|
||||||
use hex::FromHex;
|
use hex::FromHex;
|
||||||
|
|
||||||
use proxmox_router::{Router, RpcEnvironment, RpcEnvironmentType, Permission};
|
use proxmox_router::{Router, RpcEnvironment, RpcEnvironmentType, Permission};
|
||||||
use proxmox_schema::{api, ApiType, parse_property_string};
|
use proxmox_schema::{api, ApiType};
|
||||||
use proxmox_section_config::SectionConfigData;
|
use proxmox_section_config::SectionConfigData;
|
||||||
use proxmox_sys::WorkerTaskContext;
|
use proxmox_sys::WorkerTaskContext;
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ pub fn update_datastore(
|
||||||
if update.keep_yearly.is_some() { data.keep_yearly = update.keep_yearly; }
|
if update.keep_yearly.is_some() { data.keep_yearly = update.keep_yearly; }
|
||||||
|
|
||||||
if let Some(notify_str) = update.notify {
|
if let Some(notify_str) = update.notify {
|
||||||
let value = parse_property_string(¬ify_str, &DatastoreNotify::API_SCHEMA)?;
|
let value = DatastoreNotify::API_SCHEMA.parse_property_string(¬ify_str)?;
|
||||||
let notify: DatastoreNotify = serde_json::from_value(value)?;
|
let notify: DatastoreNotify = serde_json::from_value(value)?;
|
||||||
if let DatastoreNotify { gc: None, verify: None, sync: None } = notify {
|
if let DatastoreNotify { gc: None, verify: None, sync: None } = notify {
|
||||||
data.notify = None;
|
data.notify = None;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::{bail, Error};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
use proxmox_router::{Router, RpcEnvironment, RpcEnvironmentType, Permission};
|
use proxmox_router::{Router, RpcEnvironment, RpcEnvironmentType, Permission};
|
||||||
use proxmox_schema::{api, parse_property_string};
|
use proxmox_schema::api;
|
||||||
use proxmox_sys::task_log;
|
use proxmox_sys::task_log;
|
||||||
|
|
||||||
use pbs_api_types::{
|
use pbs_api_types::{
|
||||||
|
@ -173,7 +173,7 @@ pub fn create_zpool(
|
||||||
let ashift = ashift.unwrap_or(12);
|
let ashift = ashift.unwrap_or(12);
|
||||||
|
|
||||||
let devices_text = devices.clone();
|
let devices_text = devices.clone();
|
||||||
let devices = parse_property_string(&devices, &DISK_ARRAY_SCHEMA)?;
|
let devices = DISK_ARRAY_SCHEMA.parse_property_string(&devices)?;
|
||||||
let devices: Vec<String> = devices.as_array().unwrap().iter()
|
let devices: Vec<String> = devices.as_array().unwrap().iter()
|
||||||
.map(|v| v.as_str().unwrap().to_string()).collect();
|
.map(|v| v.as_str().unwrap().to_string()).collect();
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use ::serde::{Deserialize, Serialize};
|
||||||
use hex::FromHex;
|
use hex::FromHex;
|
||||||
|
|
||||||
use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
|
use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
|
||||||
use proxmox_schema::{api, parse_property_string};
|
use proxmox_schema::api;
|
||||||
|
|
||||||
use pbs_api_types::{
|
use pbs_api_types::{
|
||||||
Authid, Interface, NetworkInterfaceType, LinuxBondMode, NetworkConfigMethod, BondXmitHashPolicy,
|
Authid, Interface, NetworkInterfaceType, LinuxBondMode, NetworkConfigMethod, BondXmitHashPolicy,
|
||||||
|
@ -17,7 +17,7 @@ use pbs_config::network::{self, NetworkConfig};
|
||||||
use proxmox_rest_server::WorkerTask;
|
use proxmox_rest_server::WorkerTask;
|
||||||
|
|
||||||
fn split_interface_list(list: &str) -> Result<Vec<String>, Error> {
|
fn split_interface_list(list: &str) -> Result<Vec<String>, Error> {
|
||||||
let value = parse_property_string(&list, &NETWORK_INTERFACE_ARRAY_SCHEMA)?;
|
let value = NETWORK_INTERFACE_ARRAY_SCHEMA.parse_property_string(&list)?;
|
||||||
Ok(value.as_array().unwrap().iter().map(|v| v.as_str().unwrap().to_string()).collect())
|
Ok(value.as_array().unwrap().iter().map(|v| v.as_str().unwrap().to_string()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use serde_json::Value;
|
||||||
use proxmox_sys::fs::{replace_file, CreateOptions};
|
use proxmox_sys::fs::{replace_file, CreateOptions};
|
||||||
use proxmox_io::ReadExt;
|
use proxmox_io::ReadExt;
|
||||||
use proxmox_router::{Permission, Router, RpcEnvironment, RpcEnvironmentType};
|
use proxmox_router::{Permission, Router, RpcEnvironment, RpcEnvironmentType};
|
||||||
use proxmox_schema::{api, parse_property_string};
|
use proxmox_schema::api;
|
||||||
use proxmox_section_config::SectionConfigData;
|
use proxmox_section_config::SectionConfigData;
|
||||||
use proxmox_uuid::Uuid;
|
use proxmox_uuid::Uuid;
|
||||||
use proxmox_sys::{task_log, task_warn, WorkerTaskContext};
|
use proxmox_sys::{task_log, task_warn, WorkerTaskContext};
|
||||||
|
@ -79,7 +79,7 @@ impl TryFrom<String> for DataStoreMap {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(value: String) -> Result<Self, Error> {
|
fn try_from(value: String) -> Result<Self, Error> {
|
||||||
let value = parse_property_string(&value, &DATASTORE_MAP_ARRAY_SCHEMA)?;
|
let value = DATASTORE_MAP_ARRAY_SCHEMA.parse_property_string(&value)?;
|
||||||
let mut mapping: Vec<String> = value
|
let mut mapping: Vec<String> = value
|
||||||
.as_array()
|
.as_array()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -8,7 +8,7 @@ use tokio::signal::unix::{signal, SignalKind};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use proxmox_router::{cli::*, ApiHandler, ApiMethod, RpcEnvironment, SubRoute};
|
use proxmox_router::{cli::*, ApiHandler, ApiMethod, RpcEnvironment, SubRoute};
|
||||||
use proxmox_schema::{api, parse_parameter_strings, ApiType, ParameterSchema, Schema};
|
use proxmox_schema::{api, ApiType, ParameterSchema, Schema};
|
||||||
use proxmox_schema::format::DocumentationFormat;
|
use proxmox_schema::format::DocumentationFormat;
|
||||||
|
|
||||||
use pbs_api_types::{PROXMOX_UPID_REGEX, UPID};
|
use pbs_api_types::{PROXMOX_UPID_REGEX, UPID};
|
||||||
|
@ -161,7 +161,7 @@ fn merge_parameters(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let params = parse_parameter_strings(¶m_list, schema, true)?;
|
let params = schema.parse_parameter_strings(¶m_list, true)?;
|
||||||
|
|
||||||
Ok(params)
|
Ok(params)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use handlebars::{Handlebars, Helper, Context, RenderError, RenderContext, Output
|
||||||
|
|
||||||
use proxmox_sys::email::sendmail;
|
use proxmox_sys::email::sendmail;
|
||||||
use proxmox_lang::try_block;
|
use proxmox_lang::try_block;
|
||||||
use proxmox_schema::{parse_property_string, ApiType};
|
use proxmox_schema::ApiType;
|
||||||
|
|
||||||
use pbs_api_types::{
|
use pbs_api_types::{
|
||||||
User, TapeBackupJobSetup, SyncJobConfig, VerificationJobConfig,
|
User, TapeBackupJobSetup, SyncJobConfig, VerificationJobConfig,
|
||||||
|
@ -578,7 +578,7 @@ pub fn lookup_datastore_notify_settings(
|
||||||
|
|
||||||
let notify_str = config.notify.unwrap_or_default();
|
let notify_str = config.notify.unwrap_or_default();
|
||||||
|
|
||||||
if let Ok(value) = parse_property_string(¬ify_str, &DatastoreNotify::API_SCHEMA) {
|
if let Ok(value) = DatastoreNotify::API_SCHEMA.parse_property_string(¬ify_str) {
|
||||||
if let Ok(notify) = serde_json::from_value(value) {
|
if let Ok(notify) = serde_json::from_value(value) {
|
||||||
return (email, notify);
|
return (email, notify);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@ use anyhow::{bail, format_err, Error};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use proxmox_schema::{
|
use proxmox_schema::{ObjectSchemaType, Schema};
|
||||||
parse_property_string, parse_simple_value, verify_json_object, ObjectSchemaType, Schema,
|
|
||||||
};
|
|
||||||
|
|
||||||
type Object = serde_json::Map<String, Value>;
|
type Object = serde_json::Map<String, Value>;
|
||||||
|
|
||||||
|
@ -100,7 +98,7 @@ fn parse_key_value(
|
||||||
fn parse_value(value: &str, schema: Option<&'static Schema>) -> Result<Value, Error> {
|
fn parse_value(value: &str, schema: Option<&'static Schema>) -> Result<Value, Error> {
|
||||||
match schema {
|
match schema {
|
||||||
None => Ok(Value::String(value.to_owned())),
|
None => Ok(Value::String(value.to_owned())),
|
||||||
Some(schema) => parse_simple_value(value, schema),
|
Some(schema) => schema.parse_simple_value(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,9 +108,7 @@ pub fn from_property_string<T>(input: &str, schema: &'static Schema) -> Result<T
|
||||||
where
|
where
|
||||||
T: for<'de> Deserialize<'de>,
|
T: for<'de> Deserialize<'de>,
|
||||||
{
|
{
|
||||||
Ok(serde_json::from_value(parse_property_string(
|
Ok(serde_json::from_value(schema.parse_property_string(input)?)?)
|
||||||
input, schema,
|
|
||||||
)?)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize a data structure using a 'key: value' config file format.
|
/// Serialize a data structure using a 'key: value' config file format.
|
||||||
|
@ -124,7 +120,7 @@ pub fn to_bytes<T: Serialize>(value: &T, schema: &'static Schema) -> Result<Vec<
|
||||||
pub fn value_to_bytes(value: &Value, schema: &'static Schema) -> Result<Vec<u8>, Error> {
|
pub fn value_to_bytes(value: &Value, schema: &'static Schema) -> Result<Vec<u8>, Error> {
|
||||||
let schema = object_schema(schema)?;
|
let schema = object_schema(schema)?;
|
||||||
|
|
||||||
verify_json_object(value, schema)?;
|
schema.verify_json(value)?;
|
||||||
|
|
||||||
let object = value
|
let object = value
|
||||||
.as_object()
|
.as_object()
|
||||||
|
|
Loading…
Reference in New Issue