pub mod cli;
pub mod extract;
pub mod git;
pub mod index;
pub mod ingest;
pub mod mcp;
pub mod operations;
pub mod render;
use anybytes::Bytes;
use triblespace::core::blob::Blob;
use triblespace::core::metadata;
use triblespace::core::query::TriblePattern;
use triblespace::prelude::blobencodings::RawBytes;
use triblespace::prelude::inlineencodings::LineLocation;
use triblespace::prelude::*;
use crate::schemas::code::{
attrs, ItemKind, Language, Visibility, EXTRACTOR_RUST_SYN_V1, EXTRACTOR_RUST_SYN_V1_LAW,
EXTRACTOR_RUST_SYN_V1_NAME, KIND_ITEM, KIND_PLACEMENT, KIND_SCAN, KIND_UNIT,
};
pub use crate::schemas::code::DEFAULT_SCOPE_ID;
pub type TextHandle = Inline<inlineencodings::Handle<blobencodings::UTF8String>>;
pub type BytesHandle = Inline<inlineencodings::Handle<RawBytes>>;
pub type SpanValue = Inline<LineLocation>;
pub type IntervalValue = Inline<inlineencodings::NsTAIInterval>;
pub fn text_handle(text: &str) -> TextHandle {
let blob: Blob<blobencodings::UTF8String> = text.to_owned().to_blob();
blob.get_handle()
}
pub fn bytes_handle(bytes: &[u8]) -> BytesHandle {
let blob: Blob<RawBytes> = Bytes::from_source(bytes.to_vec()).to_blob();
blob.get_handle()
}
pub fn span_parts(span: SpanValue) -> (u64, u64, u64, u64) {
span.try_from_inline()
.expect("LineLocation decodes infallibly")
}
pub fn law_fragment() -> Fragment {
let mut fragment = Fragment::empty();
let law = fragment.put::<blobencodings::UTF8String, _>(EXTRACTOR_RUST_SYN_V1_LAW.to_owned());
let name = fragment.put::<blobencodings::UTF8String, _>(EXTRACTOR_RUST_SYN_V1_NAME.to_owned());
fragment += entity! { ExclusiveId::force_ref(&EXTRACTOR_RUST_SYN_V1) @
metadata::name: name,
metadata::description: law,
};
fragment
}
pub fn unit_core(repo: TextHandle, path: TextHandle, content: BytesHandle) -> Fragment {
entity! { _ @
metadata::tag: &KIND_UNIT,
attrs::repo: repo,
attrs::path: path,
crate::schemas::files::file::content: content,
}
}
pub fn item_core(tokens: TextHandle) -> Fragment {
entity! { _ @
metadata::tag: &KIND_ITEM,
attrs::source_tokens: tokens,
}
}
pub fn placement_core(unit: Id, item: Id, range: SpanValue) -> Fragment {
entity! { _ @
metadata::tag: &KIND_PLACEMENT,
attrs::unit: &unit,
attrs::item: &item,
attrs::source_range: range,
}
}
pub fn scan_core(repo: TextHandle, commit: TextHandle) -> Fragment {
entity! { _ @
metadata::tag: &KIND_SCAN,
attrs::repo: repo,
attrs::commit: commit,
}
}
pub fn scan_holds(scan: Id, unit: Id) -> Fragment {
entity! { ExclusiveId::force_ref(&scan) @ attrs::holds: &unit }
}
pub fn scan_annotation(scan: Id, observed_at: IntervalValue, mode: &str) -> Fragment {
let mut fragment = Fragment::empty();
let mode = fragment.put::<blobencodings::UTF8String, _>(mode.to_owned());
fragment += entity! { ExclusiveId::force_ref(&scan) @
metadata::created_at: observed_at,
metadata::description: mode,
attrs::extractor: &EXTRACTOR_RUST_SYN_V1,
};
fragment
}
pub fn unit_fragment(
repo: &str,
path: &str,
language: Language,
content: &[u8],
extracted: &extract::Extracted,
) -> (Fragment, Id) {
let mut fragment = Fragment::empty();
let repo_handle = fragment.put::<blobencodings::UTF8String, _>(repo.to_owned());
let path_handle = fragment.put::<blobencodings::UTF8String, _>(path.to_owned());
let content_handle = fragment.put::<RawBytes, _>(Bytes::from_source(content.to_vec()));
let core = unit_core(repo_handle, path_handle, content_handle);
let unit = core.root().expect("unit core has one intrinsic root");
fragment += core;
let doc = extracted
.doc
.as_ref()
.map(|doc| fragment.put::<blobencodings::UTF8String, _>(doc.clone()));
let parse_error = extracted
.parse_error
.as_ref()
.map(|error| fragment.put::<blobencodings::UTF8String, _>(error.clone()));
let import_roots: Vec<TextHandle> = extracted
.import_roots
.iter()
.map(|root| fragment.put::<blobencodings::UTF8String, _>(root.clone()))
.collect();
fragment += entity! { ExclusiveId::force_ref(&unit) @
attrs::language: language.name(),
attrs::doc?: doc,
attrs::parse_error?: parse_error,
attrs::import_root*: import_roots,
};
let mut placements: Vec<Option<Id>> = Vec::with_capacity(extracted.items.len());
for declaration in &extracted.items {
let tokens = fragment.put::<blobencodings::UTF8String, _>(declaration.tokens.clone());
let core = item_core(tokens);
let item = core.root().expect("item core has one intrinsic root");
fragment += core;
let name = declaration
.name
.as_ref()
.map(|name| fragment.put::<blobencodings::UTF8String, _>(name.clone()));
let doc = declaration
.doc
.as_ref()
.map(|doc| fragment.put::<blobencodings::UTF8String, _>(doc.clone()));
let signature = if declaration.signature.is_empty() {
None
} else {
Some(fragment.put::<blobencodings::UTF8String, _>(declaration.signature.clone()))
};
let mentions: Vec<TextHandle> = declaration
.mentions
.iter()
.map(|mention| text_handle(mention))
.collect();
fragment += entity! { ExclusiveId::force_ref(&item) @
attrs::kind: declaration.kind.name(),
attrs::visibility: declaration.visibility.name(),
metadata::name?: name,
attrs::doc?: doc,
attrs::signature?: signature,
attrs::mentions*: mentions,
};
let range: SpanValue = declaration.span.to_inline();
let core = placement_core(unit, item, range);
let placement = core.root().expect("placement core has one intrinsic root");
fragment += core;
let within = declaration
.parent
.and_then(|parent| placements.get(parent).copied().flatten());
fragment += entity! { ExclusiveId::force_ref(&placement) @
attrs::within?: within.as_ref(),
};
placements.push(Some(placement));
}
(fragment, unit)
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ScanRow {
pub id: Id,
pub repo: TextHandle,
pub commit: TextHandle,
pub observed_at: IntervalValue,
}
pub fn projected_scans<P>(facts: &P) -> Vec<ScanRow>
where
P: TriblePattern + ?Sized,
{
find!(
(id: Id, repo: TextHandle, commit: TextHandle, observed_at: IntervalValue),
pattern!(facts, [{ ?id @
metadata::tag: &KIND_SCAN,
attrs::repo: ?repo,
attrs::commit: ?commit,
metadata::created_at: ?observed_at,
}])
)
.map(|(id, repo, commit, observed_at)| ScanRow {
id,
repo,
commit,
observed_at,
})
.collect()
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Located {
pub item: Id,
pub placement: Id,
pub unit: Id,
pub range: SpanValue,
}
pub fn definitions_in_scan<P>(facts: &P, scan: Id, name: TextHandle) -> Vec<Located>
where
P: TriblePattern + ?Sized,
{
find!(
(item: Id, placement: Id, unit: Id, range: SpanValue),
pattern!(facts, [
{ scan @ attrs::holds: ?unit },
{ ?item @ metadata::name: name },
{ ?placement @
attrs::unit: ?unit,
attrs::item: ?item,
attrs::source_range: ?range },
])
)
.map(|(item, placement, unit, range)| Located {
item,
placement,
unit,
range,
})
.collect()
}
pub fn usages_in_scan<P>(facts: &P, scan: Id, identifier: TextHandle) -> Vec<Located>
where
P: TriblePattern + ?Sized,
{
find!(
(item: Id, placement: Id, unit: Id, range: SpanValue),
pattern!(facts, [
{ scan @ attrs::holds: ?unit },
{ ?item @ attrs::mentions: identifier },
{ ?placement @
attrs::unit: ?unit,
attrs::item: ?item,
attrs::source_range: ?range },
])
)
.map(|(item, placement, unit, range)| Located {
item,
placement,
unit,
range,
})
.collect()
}
pub fn placement_count_in_scan<P>(facts: &P, scan: Id) -> usize
where
P: TriblePattern + ?Sized,
{
find!(
(placement: Id, unit: Id),
pattern!(facts, [
{ scan @ attrs::holds: ?unit },
{ ?placement @ attrs::unit: ?unit },
])
)
.count()
}
pub fn units_in_scan<P>(facts: &P, scan: Id) -> Vec<Id>
where
P: TriblePattern + ?Sized,
{
find!(unit: Id, pattern!(facts, [{ scan @ attrs::holds: ?unit }])).collect()
}
pub fn unit_location<P>(facts: &P, unit: Id) -> Vec<(TextHandle, TextHandle)>
where
P: TriblePattern + ?Sized,
{
find!(
(repo: TextHandle, path: TextHandle),
pattern!(facts, [{ unit @ attrs::repo: ?repo, attrs::path: ?path }])
)
.collect()
}
pub fn unit_content<P>(facts: &P, unit: Id) -> Vec<BytesHandle>
where
P: TriblePattern + ?Sized,
{
find!(
content: BytesHandle,
pattern!(facts, [{ unit @ crate::schemas::files::file::content: ?content }])
)
.collect()
}
pub fn unit_import_roots<P>(facts: &P, unit: Id) -> Vec<TextHandle>
where
P: TriblePattern + ?Sized,
{
find!(
root: TextHandle,
pattern!(facts, [{ unit @ attrs::import_root: ?root }])
)
.collect()
}
pub fn import_root_frequency<P>(facts: &P, root: TextHandle) -> usize
where
P: TriblePattern + ?Sized,
{
find!(
unit: Id,
pattern!(facts, [{ ?unit @ attrs::import_root: root }])
)
.count()
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ItemRow {
pub kind: ItemKind,
pub visibility: Visibility,
}
pub fn item_row<P>(facts: &P, item: Id) -> Vec<ItemRow>
where
P: TriblePattern + ?Sized,
{
find!(
(kind: String, visibility: String),
pattern!(facts, [{ item @ attrs::kind: ?kind, attrs::visibility: ?visibility }])
)
.filter_map(|(kind, visibility)| {
Some(ItemRow {
kind: ItemKind::from_name(&kind)?,
visibility: Visibility::from_name(&visibility)?,
})
})
.collect()
}
pub fn item_names<P>(facts: &P, item: Id) -> Vec<TextHandle>
where
P: TriblePattern + ?Sized,
{
find!(
name: TextHandle,
pattern!(facts, [{ item @ metadata::name: ?name }])
)
.collect()
}
pub fn item_doc<P>(facts: &P, item: Id) -> Vec<TextHandle>
where
P: TriblePattern + ?Sized,
{
find!(doc: TextHandle, pattern!(facts, [{ item @ attrs::doc: ?doc }])).collect()
}
pub fn item_signature<P>(facts: &P, item: Id) -> Vec<TextHandle>
where
P: TriblePattern + ?Sized,
{
find!(
signature: TextHandle,
pattern!(facts, [{ item @ attrs::signature: ?signature }])
)
.collect()
}
pub fn unit_doc<P>(facts: &P, unit: Id) -> Vec<TextHandle>
where
P: TriblePattern + ?Sized,
{
find!(doc: TextHandle, pattern!(facts, [{ unit @ attrs::doc: ?doc }])).collect()
}
pub fn parse_failures_in_scan<P>(facts: &P, scan: Id) -> Vec<(Id, TextHandle)>
where
P: TriblePattern + ?Sized,
{
find!(
(unit: Id, error: TextHandle),
pattern!(facts, [
{ scan @ attrs::holds: ?unit },
{ ?unit @ attrs::parse_error: ?error },
])
)
.collect()
}
pub fn duplicate_placements_in_scan<P>(facts: &P, scan: Id) -> Vec<(Id, Id, Id, Id, Id)>
where
P: TriblePattern + ?Sized,
{
find!(
(item: Id, left: Id, right: Id, left_unit: Id, right_unit: Id),
pattern!(facts, [
{ scan @ attrs::holds: ?left_unit },
{ scan @ attrs::holds: ?right_unit },
{ ?left @ attrs::unit: ?left_unit, attrs::item: ?item },
{ ?right @ attrs::unit: ?right_unit, attrs::item: ?item },
])
)
.collect()
}
pub fn items_of_kind_in_scan<P>(facts: &P, scan: Id, kind: &str) -> Vec<Located>
where
P: TriblePattern + ?Sized,
{
find!(
(item: Id, placement: Id, unit: Id, range: SpanValue),
pattern!(facts, [
{ scan @ attrs::holds: ?unit },
{ ?item @ attrs::kind: kind },
{ ?placement @
attrs::unit: ?unit,
attrs::item: ?item,
attrs::source_range: ?range },
])
)
.map(|(item, placement, unit, range)| Located {
item,
placement,
unit,
range,
})
.collect()
}
pub fn items_of_kind_mentioning_in_scan<P>(
facts: &P,
scan: Id,
kind: &str,
identifier: TextHandle,
) -> Vec<Located>
where
P: TriblePattern + ?Sized,
{
find!(
(item: Id, placement: Id, unit: Id, range: SpanValue),
pattern!(facts, [
{ scan @ attrs::holds: ?unit },
{ ?item @ attrs::kind: kind, attrs::mentions: identifier },
{ ?placement @
attrs::unit: ?unit,
attrs::item: ?item,
attrs::source_range: ?range },
])
)
.map(|(item, placement, unit, range)| Located {
item,
placement,
unit,
range,
})
.collect()
}
pub fn all_item_ids<P>(facts: &P) -> Vec<Id>
where
P: TriblePattern + ?Sized,
{
find!(item: Id, pattern!(facts, [{ ?item @ metadata::tag: &KIND_ITEM }])).collect()
}
#[cfg(test)]
mod tests;