Skip to content

Commit

Permalink
Prepare for auto-generation of extension.json (#3814)
Browse files Browse the repository at this point in the history
  • Loading branch information
anchpop authored Jul 2, 2024
1 parent f0baed1 commit 931f4fa
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 11 deletions.
7 changes: 6 additions & 1 deletion docs/extension-manifest-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,12 @@
"minLength": 1
},
"values": {
"$ref": "#/definitions/ArgNumberOfValues"
"default": 1,
"allOf": [
{
"$ref": "#/definitions/ArgNumberOfValues"
}
]
}
},
"additionalProperties": false
Expand Down
73 changes: 64 additions & 9 deletions src/dfx-core/src/extension/manifest/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::error::extension::{
};
use crate::json::structure::VersionReqWithJsonSchema;
use schemars::JsonSchema;
use serde::{Deserialize, Deserializer};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;
use std::path::PathBuf;
use std::{
Expand All @@ -17,7 +17,7 @@ pub static MANIFEST_FILE_NAME: &str = "extension.json";
type SubcmdName = String;
type ArgName = String;

#[derive(Debug, Deserialize, JsonSchema)]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct ExtensionManifest {
pub name: String,
Expand All @@ -33,7 +33,7 @@ pub struct ExtensionManifest {
pub canister_type: Option<ExtensionCanisterType>,
}

#[derive(Debug, Deserialize, JsonSchema)]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum ExtensionDependency {
/// A SemVer version requirement, for example ">=0.17.0".
Expand Down Expand Up @@ -71,7 +71,7 @@ impl ExtensionManifest {
}
}

#[derive(Debug, Deserialize, JsonSchema)]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ExtensionCanisterType {
/// If one field depends on another and both specify a handlebars expression,
/// list the fields in the order that they should be evaluated.
Expand All @@ -88,18 +88,18 @@ pub struct ExtensionCanisterType {
pub defaults: BTreeMap<String, Value>,
}

#[derive(Debug, Deserialize, Default, JsonSchema)]
pub struct ExtensionSubcommandsOpts(BTreeMap<SubcmdName, ExtensionSubcommandOpts>);
#[derive(Debug, Serialize, Deserialize, Default, JsonSchema)]
pub struct ExtensionSubcommandsOpts(pub BTreeMap<SubcmdName, ExtensionSubcommandOpts>);

#[derive(Debug, Deserialize, JsonSchema)]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct ExtensionSubcommandOpts {
pub about: Option<String>,
pub args: Option<BTreeMap<ArgName, ExtensionSubcommandArgOpts>>,
pub subcommands: Option<ExtensionSubcommandsOpts>,
}

#[derive(Debug, Deserialize, JsonSchema)]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct ExtensionSubcommandArgOpts {
pub about: Option<String>,
Expand All @@ -112,7 +112,7 @@ pub struct ExtensionSubcommandArgOpts {
pub values: ArgNumberOfValues,
}

#[derive(Debug, JsonSchema)]
#[derive(Debug, JsonSchema, Eq, PartialEq)]
pub enum ArgNumberOfValues {
/// zero or more values
Number(usize),
Expand Down Expand Up @@ -167,6 +167,22 @@ impl<'de> Deserialize<'de> for ArgNumberOfValues {
}
}

impl Serialize for ArgNumberOfValues {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Number(n) => serializer.serialize_u64(*n as u64),
Self::Unlimited => serializer.serialize_str("unlimited"),
Self::Range(range) => {
let s = format!("{}..{}", range.start, range.end - 1);
serializer.serialize_str(&s)
}
}
}
}

impl ExtensionSubcommandArgOpts {
pub fn into_clap_arg(
self,
Expand Down Expand Up @@ -433,3 +449,42 @@ fn parse_test_file() {
.subcommands(&subcmds)
.debug_assert();
}

#[cfg(test)]
mod tests {
use super::*;
use serde_json;

#[test]
fn test_arg_number_of_values_number_serialization_deserialization() {
let original = ArgNumberOfValues::Number(5);
let serialized = serde_json::to_string(&original).unwrap();
let deserialized: ArgNumberOfValues = serde_json::from_str(&serialized).unwrap();

assert_eq!(serialized, "5");
assert_eq!(deserialized, ArgNumberOfValues::Number(5));
assert_eq!(original, deserialized);
}

#[test]
fn test_arg_number_of_values_unlimited_serialization_deserialization() {
let original = ArgNumberOfValues::Unlimited;
let serialized = serde_json::to_string(&original).unwrap();
let deserialized: ArgNumberOfValues = serde_json::from_str(&serialized).unwrap();

assert_eq!(serialized, "\"unlimited\"");
assert_eq!(deserialized, ArgNumberOfValues::Unlimited);
assert_eq!(original, deserialized);
}

#[test]
fn test_arg_number_of_values_range_serialization_deserialization() {
let original = ArgNumberOfValues::Range(1..4);
let serialized = serde_json::to_string(&original).unwrap();
let deserialized: ArgNumberOfValues = serde_json::from_str(&serialized).unwrap();

assert_eq!(serialized, "\"1..3\"");
assert_eq!(deserialized, ArgNumberOfValues::Range(1_usize..4_usize));
assert_eq!(original, deserialized);
}
}
2 changes: 1 addition & 1 deletion src/dfx-core/src/json/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ where
}
}

#[derive(Debug, Deserialize, JsonSchema)]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(transparent)]
pub struct VersionReqWithJsonSchema(#[schemars(with = "String")] pub VersionReq);

Expand Down

0 comments on commit 931f4fa

Please sign in to comment.