use std::fmt;
use std::path::PathBuf;
use std::sync::Arc;
use super::language::Language;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ContentHash(String);
impl ContentHash {
#[must_use]
pub fn of(bytes: &[u8]) -> Self {
Self(blake3::hash(bytes).to_hex().to_string())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
#[must_use]
pub const fn from_recorded(hex: String) -> Self {
Self(hex)
}
}
impl fmt::Display for ContentHash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TargetKind {
Library,
Binary,
Test,
Bench,
Example,
BuildScript,
Unknown,
}
impl TargetKind {
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::Library => "library",
Self::Binary => "binary",
Self::Test => "test",
Self::Bench => "bench",
Self::Example => "example",
Self::BuildScript => "build-script",
Self::Unknown => "unknown",
}
}
}
#[derive(Debug, Clone)]
pub struct SourceUnit {
pub relative_path: PathBuf,
pub absolute_path: PathBuf,
pub language: Language,
pub is_header: bool,
pub content_hash: ContentHash,
pub source_bytes: Arc<[u8]>,
pub byte_len: u64,
pub package: Option<String>,
pub crate_name: Option<String>,
pub target_kind: TargetKind,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn identical_bytes_hash_equal_and_differ_from_others() {
let a = ContentHash::of(b"fn main() {}");
let b = ContentHash::of(b"fn main() {}");
let c = ContentHash::of(b"fn main() { }");
assert_eq!(a, b);
assert_ne!(a, c);
assert_eq!(a.as_str().len(), 64);
}
#[test]
fn target_kind_names_are_stable() {
assert_eq!(TargetKind::Library.name(), "library");
assert_eq!(TargetKind::BuildScript.name(), "build-script");
assert_eq!(TargetKind::Unknown.name(), "unknown");
}
}