fix: handle nullable Cub AUR fields
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -11,28 +11,28 @@ pub struct AurPackage {
|
|||||||
#[serde(rename = "Version")]
|
#[serde(rename = "Version")]
|
||||||
pub version: String,
|
pub version: String,
|
||||||
#[serde(rename = "Description")]
|
#[serde(rename = "Description")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_nullable_string")]
|
||||||
pub description: String,
|
pub description: String,
|
||||||
#[serde(rename = "URL")]
|
#[serde(rename = "URL")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_nullable_string")]
|
||||||
pub url: String,
|
pub url: String,
|
||||||
#[serde(rename = "License")]
|
#[serde(rename = "License")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_aur_list")]
|
||||||
pub license: Vec<String>,
|
pub license: Vec<String>,
|
||||||
#[serde(rename = "Depends")]
|
#[serde(rename = "Depends")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_aur_list")]
|
||||||
pub depends: Vec<String>,
|
pub depends: Vec<String>,
|
||||||
#[serde(rename = "MakeDepends")]
|
#[serde(rename = "MakeDepends")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_aur_list")]
|
||||||
pub makedepends: Vec<String>,
|
pub makedepends: Vec<String>,
|
||||||
#[serde(rename = "OptDepends")]
|
#[serde(rename = "OptDepends")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_aur_list")]
|
||||||
pub optdepends: Vec<String>,
|
pub optdepends: Vec<String>,
|
||||||
#[serde(rename = "Provides")]
|
#[serde(rename = "Provides")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_aur_list")]
|
||||||
pub provides: Vec<String>,
|
pub provides: Vec<String>,
|
||||||
#[serde(rename = "Conflicts")]
|
#[serde(rename = "Conflicts")]
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "deserialize_aur_list")]
|
||||||
pub conflicts: Vec<String>,
|
pub conflicts: Vec<String>,
|
||||||
#[serde(rename = "NumVotes")]
|
#[serde(rename = "NumVotes")]
|
||||||
pub num_votes: u64,
|
pub num_votes: u64,
|
||||||
@@ -45,6 +45,92 @@ pub struct AurPackage {
|
|||||||
pub out_of_date: Option<bool>,
|
pub out_of_date: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_nullable_string<'de, D>(deserializer: D) -> Result<String, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
use serde::de::{self, Visitor};
|
||||||
|
|
||||||
|
struct NullableStringVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for NullableStringVisitor {
|
||||||
|
type Value = String;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("null or string")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
||||||
|
Ok(v.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
|
||||||
|
Ok(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
|
||||||
|
Ok(String::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
|
||||||
|
Ok(String::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_any(NullableStringVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_aur_list<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
use serde::de::{self, SeqAccess, Visitor};
|
||||||
|
|
||||||
|
struct AurListVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for AurListVisitor {
|
||||||
|
type Value = Vec<String>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("null, string, or array of strings")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
||||||
|
if v.is_empty() {
|
||||||
|
Ok(Vec::new())
|
||||||
|
} else {
|
||||||
|
Ok(vec![v.to_string()])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
|
||||||
|
if v.is_empty() {
|
||||||
|
Ok(Vec::new())
|
||||||
|
} else {
|
||||||
|
Ok(vec![v])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
|
||||||
|
Ok(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
|
||||||
|
Ok(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||||
|
let mut items = Vec::new();
|
||||||
|
while let Some(item) = seq.next_element::<String>()? {
|
||||||
|
items.push(item);
|
||||||
|
}
|
||||||
|
Ok(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_any(AurListVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
fn deserialize_out_of_date<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
|
fn deserialize_out_of_date<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
|
|||||||
Reference in New Issue
Block a user