Skip to main content

code_moniker_workspace/
environment.rs

1use std::path::{Path, PathBuf};
2
3use code_moniker_core::core::code_graph::CodeGraph;
4use code_moniker_core::core::moniker::Moniker;
5use code_moniker_core::core::uri::{UriConfig, to_uri};
6use code_moniker_core::lang::Lang;
7
8pub type ExtractContext = crate::extract::Context;
9pub type IdentityResolver = crate::source::LocalIdentityResolver;
10pub type IndexedSourceMaterial = crate::source::CodeIndexMaterial;
11pub type ResourceCache = crate::source::LocalResourceCache;
12pub type SourceFile = crate::sources::SourceFile;
13pub type SourceFileSet = crate::sources::SourceSet;
14pub type SourceRoot = crate::sources::SourceRoot;
15
16pub fn discover_sources(
17	paths: &[PathBuf],
18	project: Option<String>,
19) -> anyhow::Result<SourceFileSet> {
20	crate::sources::discover(paths, project)
21}
22
23pub fn discover_source_files(
24	root: &Path,
25	files: &[PathBuf],
26	project: Option<String>,
27) -> anyhow::Result<SourceFileSet> {
28	crate::sources::discover_files(root, files, project)
29}
30
31pub fn language_for_path(path: &Path) -> anyhow::Result<Lang> {
32	Ok(crate::lang::path_to_lang(path)?)
33}
34
35pub fn load_or_extract_source(
36	path: &Path,
37	anchor: &Path,
38	lang: Lang,
39	cache_dir: Option<&Path>,
40	ctx: &ExtractContext,
41) -> anyhow::Result<(CodeGraph, Option<String>)> {
42	Ok(crate::cache::load_or_extract_result(
43		path, anchor, lang, cache_dir, ctx,
44	)?)
45}
46
47pub fn cached_index_material(
48	cache: &ResourceCache,
49	generation: crate::snapshot::ResourceGeneration,
50) -> Option<std::sync::Arc<IndexedSourceMaterial>> {
51	cache.index_material(generation)
52}
53
54pub fn next_resource_generation(cache: &ResourceCache) -> crate::snapshot::ResourceGeneration {
55	cache.next_generation()
56}
57
58#[cfg(test)]
59pub fn extract_source(lang: Lang, source: &str, path: &Path) -> CodeGraph {
60	crate::extract::extract(lang, source, path)
61}
62
63pub fn extract_source_with(
64	lang: Lang,
65	source: &str,
66	path: &Path,
67	ctx: &ExtractContext,
68) -> CodeGraph {
69	crate::extract::extract_with(lang, source, path, ctx)
70}
71
72pub fn line_range(source: &str, start: u32, end: u32) -> (u32, u32) {
73	crate::lines::line_range(source, start, end)
74}
75
76pub fn compact_moniker(moniker: &Moniker, scheme: &str) -> String {
77	render_compact_moniker(moniker).unwrap_or_else(|| to_uri(moniker, &UriConfig { scheme }))
78}
79
80fn render_compact_moniker(moniker: &Moniker) -> Option<String> {
81	let view = moniker.as_view();
82	let mut lang: Option<String> = None;
83	let mut packages: Vec<String> = Vec::new();
84	let mut dirs: Vec<String> = Vec::new();
85	let mut modules: Vec<String> = Vec::new();
86	let mut rest: Vec<(String, String)> = Vec::new();
87	for segment in view.segments() {
88		let kind = std::str::from_utf8(segment.kind).ok()?.to_string();
89		let name = std::str::from_utf8(segment.name).ok()?.to_string();
90		match kind.as_str() {
91			"lang" => lang = Some(name),
92			"package" => packages.push(name),
93			"dir" => dirs.push(name),
94			"module" => modules.push(name),
95			_ => rest.push((kind, name)),
96		}
97	}
98	let head = lang.unwrap_or_else(|| {
99		std::str::from_utf8(view.project())
100			.unwrap_or(".")
101			.to_string()
102	});
103	if packages.is_empty() && dirs.is_empty() && modules.is_empty() && rest.is_empty() {
104		return Some(head);
105	}
106	let mut out = String::new();
107	out.push_str(&head);
108	out.push(':');
109	let mut wrote_scope = false;
110	if !packages.is_empty() {
111		out.push_str(&packages.join("."));
112		wrote_scope = true;
113	} else if !dirs.is_empty() {
114		out.push_str(&dirs.join("/"));
115		wrote_scope = true;
116	}
117	let has_module = !modules.is_empty();
118	if has_module {
119		if wrote_scope {
120			out.push('/');
121		}
122		out.push_str(&modules.join("."));
123	}
124	for (idx, (kind, name)) in rest.iter().enumerate() {
125		if idx == 0 && has_module {
126			out.push('.');
127		} else if wrote_scope || has_module || idx > 0 {
128			out.push('/');
129		}
130		out.push_str(kind);
131		out.push(':');
132		out.push_str(name);
133	}
134	Some(out)
135}