fn deserialize()

in guppy/src/graph/summaries/package_set.rs [398:505]


    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let fields = ThirdPartySelectFields::deserialize(deserializer)?;

        // Look for incompatible fields.
        let mut found_sources = vec![];
        if fields.path.is_some() {
            found_sources.push("`path`");
        }
        if fields.registry.is_some() {
            found_sources.push("`registry`");
        }
        if fields.git.is_some() {
            found_sources.push("`git`");
        }
        if fields.url.is_some() {
            found_sources.push("`url`");
        }

        let mut found_git = vec![];
        if fields.branch.is_some() {
            found_git.push("`branch`");
        }
        if fields.tag.is_some() {
            found_git.push("`tag`");
        }
        if fields.rev.is_some() {
            found_git.push("`rev`");
        }

        // Only one of the above fields can be present.
        if found_sources.len() > 1 {
            return Err(serde::de::Error::custom(format!(
                "for package {}, only one of {} can be present",
                fields.name,
                found_sources.join(", ")
            )));
        }

        let source = if let Some(path) = fields.path {
            if !found_git.is_empty() {
                return Err(serde::de::Error::custom(format!(
                    "for package {}, `path` incompatible with {}",
                    fields.name,
                    found_git.join(", ")
                )));
            }

            ThirdPartySource::Path(path)
        } else if let Some(git) = fields.git {
            if found_git.len() > 1 {
                return Err(serde::de::Error::custom(format!(
                    "for package {}, only one of {} can be present",
                    fields.name,
                    found_git.join(", ")
                )));
            }

            let req = if let Some(branch) = fields.branch {
                GitReqSummary::Branch(branch.into_owned())
            } else if let Some(tag) = fields.tag {
                GitReqSummary::Tag(tag.into_owned())
            } else if let Some(rev) = fields.rev {
                GitReqSummary::Rev(rev.into_owned())
            } else {
                GitReqSummary::Default
            };

            ThirdPartySource::Git {
                repo: git.into_owned(),
                req,
            }
        } else if let Some(url) = fields.url {
            if !found_git.is_empty() {
                return Err(serde::de::Error::custom(format!(
                    "for package {}, `url` incompatible with {}",
                    fields.name,
                    found_git.join(", ")
                )));
            }
            ThirdPartySource::Url(url.into_owned())
        } else {
            if !found_git.is_empty() {
                if fields.registry.is_some() {
                    return Err(serde::de::Error::custom(format!(
                        "for package {}, `registry` incompatible with {}",
                        fields.name,
                        found_git.join(", "),
                    )));
                } else {
                    return Err(serde::de::Error::custom(format!(
                        "for package {}, `git` required for {}",
                        fields.name,
                        found_git.join(", "),
                    )));
                }
            }
            ThirdPartySource::Registry(fields.registry.map(|registry| registry.into_owned()))
        };

        Ok(Self {
            name: fields.name.into_owned(),
            version: fields.version,
            source,
        })
    }