use triblespace::macros::id_hex;
use triblespace::prelude::*;
pub const DEFAULT_SCOPE_ID: Id = id_hex!("EB416080F8F2C34CA05598C4FCBA3535");
pub const KIND_UNIT: Id = id_hex!("A52225D11B70645750139A3776DD3230");
pub const KIND_ITEM: Id = id_hex!("47F7160C12A15702D5A3DFB5227FE79C");
pub const KIND_PLACEMENT: Id = id_hex!("34E05E4F4155C853CD97C2D58B647CBF");
pub const KIND_SCAN: Id = id_hex!("3213AAE6414EEEAAA712C17ED5CBD308");
pub const EXTRACTOR_RUST_SYN_V1: Id = id_hex!("603D7068C8F1B92D5D20AA9206ABF467");
pub const EXTRACTOR_RUST_SYN_V1_NAME: &str = "rust-syn-v1";
pub const EXTRACTOR_RUST_SYN_V1_LAW: &str = "\
Rust declarations are located with syn's item visitor over a file whose leading \
`#!` shebang line (not `#![`) has been stripped. Each visited declaration \
becomes one item. Its token stream is normalized by walking the item's tokens \
depth-first, emitting each leaf token's textual spelling, emitting a group's \
delimiters as their literal open and close characters around its contents, and \
joining every emitted piece with a single ASCII space. Whitespace, formatting \
and plain `//` comments therefore do not participate in identity, while `///` \
doc comments do, because they are `#[doc = \"...\"]` tokens. A mention is any \
identifier the declaration syntactically names, including every segment of a \
path, the full `::`-joined spelling of that path, and identifiers and paths \
recovered from inside macro token streams; mentions are unresolved, so they \
witness spelling rather than binding. A file that does not parse yields a unit \
carrying a parse error and no items.";
pub mod attrs {
use super::*;
attributes! {
"8FBE9F0E3A11E45DBAC45692DDB44514" as repo:
inlineencodings::Handle<blobencodings::UTF8String>;
"32CDF6DB5C03778BE5EFD193B7421957" as path:
inlineencodings::Handle<blobencodings::UTF8String>;
"35F62EB70939951867305D9D986AE68C" as language: inlineencodings::ShortString;
"4D5F0C0A0778939732A813D4100149CC" as doc:
inlineencodings::Handle<blobencodings::UTF8String>;
"CE2FACA8CFB8FABE1D3C54498D6374E3" as parse_error:
inlineencodings::Handle<blobencodings::UTF8String>;
"22CAE18A57BDA43133B65547A6689663" as import_root:
inlineencodings::Handle<blobencodings::UTF8String>;
"A0ED33675DF3B92867FD68177794BEDD" as kind: inlineencodings::ShortString;
"41DAF4F9B5A081674E272996B89D818F" as visibility: inlineencodings::ShortString;
"6937C17DB1414657A0578447A8F6EAE3" as signature:
inlineencodings::Handle<blobencodings::UTF8String>;
"9ECEFFBFC44F689A941C1214E0BF4C46" as mentions:
inlineencodings::Handle<blobencodings::UTF8String>;
"7E04326235C8A7A7EB1C3F8CB07C8A7F" as unit: inlineencodings::GenId;
"AEE10E1CADC91638D3906B40C3790723" as item: inlineencodings::GenId;
"11A6CB6787AB1BFA17B25579239670F2" as within: inlineencodings::GenId;
"D2C9BF2E62C5EAFFA2299BB2B58747DA" as commit:
inlineencodings::Handle<blobencodings::UTF8String>;
"110B07579AB1B8E3E95B7239B82AF1C0" as holds: inlineencodings::GenId;
"F7DF8119B5470CF8BF692C5C5B5680B3" as extractor: inlineencodings::GenId;
"8ED33DA54C226ADEA0FFF7863563DF5F" unsafe as source_range:
inlineencodings::LineLocation;
"B981AEA9437561F8DB96E7EECBB94BFD" unsafe as source_tokens:
inlineencodings::Handle<blobencodings::UTF8String>;
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Language {
Rust,
Toml,
Markdown,
Shell,
Typst,
Text,
}
impl Language {
pub fn name(self) -> &'static str {
match self {
Self::Rust => "rust",
Self::Toml => "toml",
Self::Markdown => "markdown",
Self::Shell => "shell",
Self::Typst => "typst",
Self::Text => "text",
}
}
pub fn from_name(name: &str) -> Option<Self> {
match name {
"rust" => Some(Self::Rust),
"toml" => Some(Self::Toml),
"markdown" => Some(Self::Markdown),
"shell" => Some(Self::Shell),
"typst" => Some(Self::Typst),
"text" => Some(Self::Text),
_ => None,
}
}
pub fn of_path(path: &str) -> Option<Self> {
let name = path.rsplit('/').next().unwrap_or(path);
if let Some(extension) = name.rsplit_once('.').map(|(_, extension)| extension) {
return match extension {
"rs" => Some(Self::Rust),
"toml" => Some(Self::Toml),
"md" => Some(Self::Markdown),
"sh" | "bash" | "zsh" => Some(Self::Shell),
"typ" => Some(Self::Typst),
"txt" => Some(Self::Text),
_ => None,
};
}
None
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum ItemKind {
Fn,
Struct,
Enum,
Union,
Trait,
Impl,
Mod,
Use,
Const,
Static,
Type,
Macro,
Extern,
}
impl ItemKind {
pub fn name(self) -> &'static str {
match self {
Self::Fn => "fn",
Self::Struct => "struct",
Self::Enum => "enum",
Self::Union => "union",
Self::Trait => "trait",
Self::Impl => "impl",
Self::Mod => "mod",
Self::Use => "use",
Self::Const => "const",
Self::Static => "static",
Self::Type => "type",
Self::Macro => "macro",
Self::Extern => "extern",
}
}
pub fn from_name(name: &str) -> Option<Self> {
match name {
"fn" => Some(Self::Fn),
"struct" => Some(Self::Struct),
"enum" => Some(Self::Enum),
"union" => Some(Self::Union),
"trait" => Some(Self::Trait),
"impl" => Some(Self::Impl),
"mod" => Some(Self::Mod),
"use" => Some(Self::Use),
"const" => Some(Self::Const),
"static" => Some(Self::Static),
"type" => Some(Self::Type),
"macro" => Some(Self::Macro),
"extern" => Some(Self::Extern),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Visibility {
Public,
Crate,
Super,
Restricted,
Private,
}
impl Visibility {
pub fn name(self) -> &'static str {
match self {
Self::Public => "pub",
Self::Crate => "crate",
Self::Super => "super",
Self::Restricted => "restricted",
Self::Private => "private",
}
}
pub fn from_name(name: &str) -> Option<Self> {
match name {
"pub" => Some(Self::Public),
"crate" => Some(Self::Crate),
"super" => Some(Self::Super),
"restricted" => Some(Self::Restricted),
"private" => Some(Self::Private),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_closed_vocabulary_value_fits_a_short_string() {
for name in [
Language::Rust.name(),
Language::Toml.name(),
Language::Markdown.name(),
Language::Shell.name(),
Language::Typst.name(),
Language::Text.name(),
] {
assert!(name.len() <= 32, "{name} overflows ShortString");
}
for kind in [
ItemKind::Fn,
ItemKind::Struct,
ItemKind::Enum,
ItemKind::Union,
ItemKind::Trait,
ItemKind::Impl,
ItemKind::Mod,
ItemKind::Use,
ItemKind::Const,
ItemKind::Static,
ItemKind::Type,
ItemKind::Macro,
ItemKind::Extern,
] {
assert!(
kind.name().len() <= 32,
"{} overflows ShortString",
kind.name()
);
}
for visibility in [
Visibility::Public,
Visibility::Crate,
Visibility::Super,
Visibility::Restricted,
Visibility::Private,
] {
assert!(visibility.name().len() <= 32);
}
}
#[test]
fn a_language_name_round_trips() {
for language in [
Language::Rust,
Language::Toml,
Language::Markdown,
Language::Shell,
Language::Typst,
Language::Text,
] {
assert_eq!(Language::from_name(language.name()), Some(language));
}
}
#[test]
fn a_path_this_build_cannot_model_has_no_language() {
assert_eq!(Language::of_path("src/lib.rs"), Some(Language::Rust));
assert_eq!(Language::of_path("Cargo.toml"), Some(Language::Toml));
assert_eq!(
Language::of_path("book/src/pile.md"),
Some(Language::Markdown)
);
assert_eq!(Language::of_path("scripts/install"), None);
assert_eq!(Language::of_path("assets/logo.png"), None);
}
}