Skip to content

Commit 40cdb71

Browse files
author
Nichol Yip
committed
Added LintedSpec type to return lint warnings
Signed-off-by: Nichol Yip <[email protected]>
1 parent 35e5e97 commit 40cdb71

File tree

1 file changed

+100
-74
lines changed

1 file changed

+100
-74
lines changed

crates/spk-schema/src/v0/spec.rs

Lines changed: 100 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ pub struct Spec<Ident> {
8383

8484
#[derive(Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd, Serialize)]
8585
pub struct LintedSpec<Ident> {
86-
spec: Spec<Ident>,
87-
lints: Vec<String>,
86+
pub spec: Spec<Ident>,
87+
pub lints: Vec<String>,
8888
}
8989

9090
impl<Ident> Spec<Ident> {
@@ -730,7 +730,7 @@ where
730730
where
731731
D: serde::de::Deserializer<'de>,
732732
{
733-
deserializer.deserialize_map(SpecVisitor::recipe())
733+
Ok(std::convert::Into::<Spec<VersionIdent>>::into(deserializer.deserialize_map(SpecVisitor::recipe())?))
734734
}
735735
}
736736

@@ -742,7 +742,7 @@ where
742742
where
743743
D: serde::de::Deserializer<'de>,
744744
{
745-
let mut spec = deserializer.deserialize_map(SpecVisitor::default())?;
745+
let mut spec: Spec<AnyIdent> = deserializer.deserialize_map(SpecVisitor::default())?.into();
746746
if spec.pkg.is_source() {
747747
// for backward-compatibility with older publishes, prune out anything
748748
// that is not relevant to a source package, since now source packages
@@ -761,7 +761,7 @@ where
761761
where
762762
D: serde::de::Deserializer<'de>,
763763
{
764-
let mut spec = deserializer.deserialize_map(SpecVisitor::package())?;
764+
let mut spec: Spec<BuildIdent> = deserializer.deserialize_map(SpecVisitor::package())?.into();
765765
if spec.pkg.is_source() {
766766
// for backward-compatibility with older publishes, prune out anything
767767
// that is not relevant to a source package, since now source packages
@@ -781,7 +781,7 @@ where
781781
where
782782
D: serde::de::Deserializer<'de>,
783783
{
784-
deserializer.deserialize_map(SpecVisitor::recipe()).into()
784+
Ok(std::convert::Into::<LintedSpec<VersionIdent>>::into(deserializer.deserialize_map(SpecVisitor::recipe())?))
785785
}
786786
}
787787

@@ -793,7 +793,7 @@ where
793793
where
794794
D: serde::de::Deserializer<'de>,
795795
{
796-
let mut spec: LintedSpec<AnyIdent> = deserializer.deserialize_map(SpecVisitor::default()).into();
796+
let mut spec: LintedSpec<AnyIdent> = deserializer.deserialize_map(SpecVisitor::default())?.into();
797797
if spec.spec.pkg.is_source() {
798798
// for backward-compatibility with older publishes, prune out anything
799799
// that is not relevant to a source package, since now source packages
@@ -812,7 +812,7 @@ where
812812
where
813813
D: serde::de::Deserializer<'de>,
814814
{
815-
let mut spec: LintedSpec<BuildIdent> = deserializer.deserialize_map(SpecVisitor::package()).into();
815+
let mut spec: LintedSpec<BuildIdent> = deserializer.deserialize_map(SpecVisitor::package())?.into();
816816
if spec.spec.pkg.is_source() {
817817
// for backward-compatibility with older publishes, prune out anything
818818
// that is not relevant to a source package, since now source packages
@@ -854,59 +854,72 @@ impl<B, T> Default for SpecVisitor<B, T> {
854854
}
855855
}
856856

857-
impl<'de, A, B, T> From<SpecVisitor<B, T>> for LintedSpec<Ident<B, T>>
857+
impl<B, T> From<SpecVisitor<B, T>> for LintedSpec<Ident<B, T>>
858858
where
859-
A: serde::de::MapAccess<'de>,
860859
Ident<B, T>: serde::de::DeserializeOwned,
861860
{
862-
fn from(mut map: A) -> std::result::Result<Self, A::Error>
863-
{
864-
let visitor = SpecVisitor::default();
865-
while let Some(key) = map.next_key::<Stringified>()? {
866-
match key.as_str() {
867-
"pkg" => visitor.pkg = Some(map.next_value::<Ident<B, T>>()?),
868-
"meta" => visitor.meta = Some(map.next_value::<Meta>()?),
869-
"compat" => visitor.compat = Some(map.next_value::<Compat>()?),
870-
"deprecated" => visitor.deprecated = Some(map.next_value::<bool>()?),
871-
"sources" => visitor.sources = Some(map.next_value::<Vec<SourceSpec>>()?),
872-
"build" => visitor.build = Some(map.next_value::<UncheckedBuildSpec>()?),
873-
"tests" => visitor.tests = Some(map.next_value::<Vec<TestSpec>>()?),
874-
"install" => visitor.install = Some(map.next_value::<InstallSpec>()?),
875-
unknown_key => {
876-
visitor.lints.push(format!("Unrecognized key {unknown_key}"));
877-
map.next_value::<serde::de::IgnoredAny>()?;
878-
}
879-
}
880-
}
881-
882-
let pkg = visitor
883-
.pkg
884-
.take()
885-
.ok_or_else(|| serde::de::Error::missing_field("pkg"))?;
886-
887-
Ok(LintedSpec {
861+
fn from(mut value: SpecVisitor<B, T>) -> Self {
862+
Self {
888863
spec: Spec {
889-
meta: visitor.meta.take().unwrap_or_default(),
890-
compat: visitor.compat.take().unwrap_or_default(),
891-
deprecated: visitor.deprecated.take().unwrap_or_default(),
892-
sources: visitor
864+
pkg: value.pkg.expect("Missing field: pkg"),
865+
meta: value.meta.take().unwrap_or_default(),
866+
compat: value.compat.take().unwrap_or_default(),
867+
deprecated: value.deprecated.take().unwrap_or_default(),
868+
sources: value
893869
.sources
894870
.take()
895871
.unwrap_or_else(|| vec![SourceSpec::Local(LocalSource::default())]),
896-
build: match visitor.build.take() {
897-
Some(build_spec) if !visitor.check_build_spec => {
872+
build: match value.build.take() {
873+
Some(build_spec) if !value.check_build_spec => {
898874
// Safety: see the SpecVisitor::package constructor
899875
unsafe { build_spec.into_inner() }
900876
}
901-
Some(build_spec) => build_spec.try_into().map_err(serde::de::Error::custom)?,
877+
Some(build_spec) => {
878+
match build_spec.try_into() {
879+
Ok(b) => b,
880+
Err(_) => BuildSpec::default(),
881+
}
882+
},
902883
None => Default::default(),
903884
},
904-
tests: visitor.tests.take().unwrap_or_default(),
905-
install: visitor.install.take().unwrap_or_default(),
906-
pkg,
885+
tests: value.tests.take().unwrap_or_default(),
886+
install: value.install.take().unwrap_or_default(),
887+
},
888+
lints: value.lints
889+
}
890+
}
891+
}
892+
893+
impl<B, T> From<SpecVisitor<B, T>> for Spec<Ident<B, T>>
894+
where
895+
Ident<B, T>: serde::de::DeserializeOwned,
896+
{
897+
fn from(mut value: SpecVisitor<B, T>) -> Self {
898+
Self {
899+
pkg: value.pkg.expect("Missing field pkg"),
900+
meta: value.meta.take().unwrap_or_default(),
901+
compat: value.compat.take().unwrap_or_default(),
902+
deprecated: value.deprecated.take().unwrap_or_default(),
903+
sources: value
904+
.sources
905+
.take()
906+
.unwrap_or_else(|| vec![SourceSpec::Local(LocalSource::default())]),
907+
build: match value.build.take() {
908+
Some(build_spec) if !value.check_build_spec => {
909+
// Safety: see the SpecVisitor::package constructor
910+
unsafe { build_spec.into_inner() }
911+
}
912+
Some(build_spec) => {
913+
match build_spec.try_into() {
914+
Ok(b) => b,
915+
Err(_) => BuildSpec::default(),
916+
}
917+
},
918+
None => Default::default(),
907919
},
908-
lints: visitor.lints
909-
})
920+
tests: value.tests.take().unwrap_or_default(),
921+
install: value.install.take().unwrap_or_default(),
922+
}
910923
}
911924
}
912925

@@ -935,7 +948,7 @@ impl<'de, B, T> serde::de::Visitor<'de> for SpecVisitor<B, T>
935948
where
936949
Ident<B, T>: serde::de::DeserializeOwned,
937950
{
938-
type Value = Spec<Ident<B, T>>;
951+
type Value = SpecVisitor<B, T>;
939952

940953
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
941954
f.write_str("a package specification")
@@ -955,37 +968,50 @@ where
955968
"build" => self.build = Some(map.next_value::<UncheckedBuildSpec>()?),
956969
"tests" => self.tests = Some(map.next_value::<Vec<TestSpec>>()?),
957970
"install" => self.install = Some(map.next_value::<InstallSpec>()?),
958-
_ => {
971+
unrecognized_string => {
972+
self.lints.push(format!("unrecognized string {unrecognized_string}"));
959973
// ignore any unrecognized field, but consume the value anyway
960974
// TODO: could we warn about fields that look like typos?
961975
map.next_value::<serde::de::IgnoredAny>()?;
962976
}
963977
}
964978
}
965979

966-
let pkg = self
967-
.pkg
968-
.take()
969-
.ok_or_else(|| serde::de::Error::missing_field("pkg"))?;
970-
Ok(Spec {
971-
meta: self.meta.take().unwrap_or_default(),
972-
compat: self.compat.take().unwrap_or_default(),
973-
deprecated: self.deprecated.take().unwrap_or_default(),
974-
sources: self
975-
.sources
976-
.take()
977-
.unwrap_or_else(|| vec![SourceSpec::Local(LocalSource::default())]),
978-
build: match self.build.take() {
979-
Some(build_spec) if !self.check_build_spec => {
980-
// Safety: see the SpecVisitor::package constructor
981-
unsafe { build_spec.into_inner() }
982-
}
983-
Some(build_spec) => build_spec.try_into().map_err(serde::de::Error::custom)?,
984-
None => Default::default(),
985-
},
986-
tests: self.tests.take().unwrap_or_default(),
987-
install: self.install.take().unwrap_or_default(),
988-
pkg,
989-
})
980+
self.pkg.as_ref().ok_or_else(|| serde::de::Error::missing_field("pkg"))?;
981+
// match self.build {
982+
// Some(build_spec) if !self.check_build_spec => {
983+
// // Safety: see the SpecVisitor::package constructor
984+
// unsafe { build_spec.into_inner(); }
985+
// },
986+
// Some(build_spec) => build_spec.try_into().map_err(serde::de::Error::custom)?,
987+
// _ => (),
988+
// }
989+
Ok(self.into())
990+
991+
// let pkg = self
992+
// .pkg
993+
// .take()
994+
// .ok_or_else(|| serde::de::Error::missing_field("pkg"))?;
995+
// Ok(S {
996+
// meta: self.meta.take().unwrap_or_default(),
997+
// compat: self.compat.take().unwrap_or_default(),
998+
// deprecated: self.deprecated.take().unwrap_or_default(),
999+
// sources: self
1000+
// .sources
1001+
// .take()
1002+
// .unwrap_or_else(|| vec![SourceSpec::Local(LocalSource::default())]),
1003+
// build: match self.build.take() {
1004+
// Some(build_spec) if !self.check_build_spec => {
1005+
// // Safety: see the SpecVisitor::package constructor
1006+
// unsafe { build_spec.into_inner() }
1007+
// }
1008+
// Some(build_spec) => build_spec.try_into().map_err(serde::de::Error::custom)?,
1009+
// None => Default::default(),
1010+
// },
1011+
// tests: self.tests.take().unwrap_or_default(),
1012+
// install: self.install.take().unwrap_or_default(),
1013+
// pkg,
1014+
// })
9901015
}
9911016
}
1017+

0 commit comments

Comments
 (0)