rune/cli/
naming.rs

1use std::ffi::OsStr;
2
3use crate::alloc::prelude::*;
4use crate::alloc::{self, HashMap};
5use crate::cli::EntryPoint;
6use crate::item::ComponentRef;
7use crate::ItemBuf;
8
9/// Helper to perform non-conflicting crate naming.
10#[derive(Default)]
11pub(crate) struct Naming {
12    names: HashMap<ItemBuf, usize>,
13}
14
15impl Naming {
16    /// Construct a unique crate name for the given entrypoint.
17    pub(crate) fn item(&mut self, e: &EntryPoint<'_>) -> alloc::Result<ItemBuf> {
18        let mut item = match &e {
19            EntryPoint::Path(path, _) => match path.file_stem().and_then(OsStr::to_str) {
20                Some(name) => ItemBuf::with_crate(name)?,
21                None => ItemBuf::with_crate("entry")?,
22            },
23            EntryPoint::Package(p) => {
24                let name = p.found.name.as_str();
25                ItemBuf::with_crate_item(&p.package.name, [name])?
26            }
27        };
28
29        let values = self.names.entry(item.try_clone()?).or_try_default()?;
30
31        if *values > 0 {
32            let name = try_format!("{}", *values - 1);
33            item.push(ComponentRef::Str(&name))?;
34        }
35
36        *values += 1;
37        Ok(item)
38    }
39}