Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::collections::{BTreeSet, HashMap};
use crate::*;
use anyhow::{bail, Result};
type MetadataGroupMap = HashMap<String, MetadataGroup>;
// Create empty metadata groups based on the metadata items.
pub fn create_metadata_groups(items: &[Metadata]) -> MetadataGroupMap {
// Map crate names to MetadataGroup instances
items
.iter()
.filter_map(|i| match i {
Metadata::Namespace(namespace) => {
let group = MetadataGroup {
namespace: namespace.clone(),
namespace_docstring: None,
items: BTreeSet::new(),
};
Some((namespace.crate_name.clone(), group))
}
Metadata::UdlFile(udl) => {
let namespace = NamespaceMetadata {
crate_name: udl.module_path.clone(),
name: udl.namespace.clone(),
};
let group = MetadataGroup {
namespace,
namespace_docstring: None,
items: BTreeSet::new(),
};
Some((udl.module_path.clone(), group))
}
_ => None,
})
.collect::<HashMap<_, _>>()
}
/// Consume the items into the previously created metadata groups.
pub fn group_metadata(group_map: &mut MetadataGroupMap, items: Vec<Metadata>) -> Result<()> {
for item in items {
if matches!(&item, Metadata::Namespace(_)) {
continue;
}
let crate_name = calc_crate_name(item.module_path()).to_owned();
let group = match group_map.get_mut(&crate_name) {
Some(ns) => ns,
None => bail!("Unknown namespace for {item:?} ({crate_name})"),
};
if group.items.contains(&item) {
bail!("Duplicate metadata item: {item:?}");
}
group.add_item(item);
}
Ok(())
}
#[derive(Debug)]
pub struct MetadataGroup {
pub namespace: NamespaceMetadata,
pub namespace_docstring: Option<String>,
pub items: BTreeSet<Metadata>,
}
impl MetadataGroup {
pub fn add_item(&mut self, item: Metadata) {
self.items.insert(item);
}
}
fn calc_crate_name(module_path: &str) -> &str {
module_path.split("::").next().unwrap()
}