-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat:
cargo run
works with free main components (load, analyze, pub…
…lish) in place (nothing producing just yet)
- Loading branch information
Showing
13 changed files
with
336 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
mod model; | ||
mod output; | ||
mod source; | ||
mod util; | ||
pub use { | ||
model::doc_model::DocumentationModel, | ||
output::typst::TypstGenerator, | ||
source::owl::OWLSource, | ||
util::{rdf_load, setup_tracing}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,46 @@ | ||
fn main() { | ||
println!("Hello, world!"); | ||
use { | ||
console::style, | ||
grapharch::{ | ||
DocumentationModel, | ||
OWLSource, | ||
TypstGenerator, | ||
setup_tracing, | ||
}, | ||
tracing::{error, info}, | ||
}; | ||
|
||
async fn run() -> anyhow::Result<()> { | ||
setup_tracing()?; | ||
|
||
// Read the OWL file | ||
let owl_url = "https://ekgf.github.io/dprod/dprod.ttl"; | ||
let mut owl_source = OWLSource::new(owl_url).map_err(|e| { | ||
error!( | ||
"{}: {}. URL: {}", | ||
style("Failed to initialize OWLSource").red(), | ||
e, | ||
owl_url | ||
); | ||
|
||
anyhow::Error::msg(format!("{}: URL: {}", e, owl_url)) | ||
})?; | ||
|
||
// Process the OWL file | ||
let mut doc_model = DocumentationModel::new()?; | ||
owl_source.analyze(&mut doc_model).await?; | ||
|
||
// Generate output | ||
let typst_gen = TypstGenerator::new("output"); | ||
typst_gen.generate(doc_model.get_store())?; | ||
|
||
info!("Documentation generation completed successfully."); | ||
Ok(()) | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
if let Err(e) = run().await { | ||
error!("Application error: {}", e); | ||
std::process::exit(1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use oxigraph::{model::Quad, store::Store}; | ||
|
||
pub struct DocumentationModel { | ||
store: Store, | ||
} | ||
|
||
impl DocumentationModel { | ||
pub fn new() -> anyhow::Result<Self> { | ||
Ok(Self { store: Store::new()? }) | ||
} | ||
|
||
pub async fn add_documentable_item( | ||
&mut self, | ||
quad: Quad, | ||
) -> anyhow::Result<()> { | ||
self.store.insert(&quad)?; | ||
Ok(()) | ||
} | ||
|
||
pub fn get_store(&self) -> &Store { &self.store } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod doc_model; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod typst; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use {oxigraph::store::Store, std::path::Path}; | ||
|
||
pub struct TypstGenerator { | ||
#[allow(dead_code)] | ||
output_dir: String, | ||
} | ||
|
||
impl TypstGenerator { | ||
pub fn new<P: AsRef<Path>>(output_dir: P) -> Self { | ||
Self { | ||
output_dir: output_dir | ||
.as_ref() | ||
.to_string_lossy() | ||
.into_owned(), | ||
} | ||
} | ||
|
||
pub fn generate(&self, _store: &Store) -> anyhow::Result<()> { | ||
// TODO: Query the store and generate Typst documentation | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod owl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use { | ||
crate::{model::doc_model::DocumentationModel, rdf_load}, | ||
console::style, | ||
oxigraph::{model::*, store::Store}, | ||
std::path::Path, | ||
tracing::{error, info}, | ||
}; | ||
|
||
pub struct OWLSource { | ||
/// A temporary store that just holds the data from the source | ||
store: Store, | ||
file_path: String, | ||
graph: GraphName, | ||
base_iri: String, | ||
} | ||
|
||
impl OWLSource { | ||
pub fn new<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> { | ||
info!( | ||
"{}", | ||
style("Starting OWL source...").green().bold() | ||
); | ||
Ok(Self { | ||
store: Store::new()?, | ||
file_path: path.as_ref().to_string_lossy().into_owned(), | ||
graph: NamedNodeRef::new("http://example.com/g2")? | ||
.into(), | ||
base_iri: "http://example.com".to_string(), | ||
}) | ||
} | ||
|
||
/// Load the data from the source into the store. | ||
/// Note that this is not the same store as the store held by the | ||
/// documentation model. This store is temporary and is used to | ||
/// hold the data from the source. | ||
async fn load(&mut self) -> anyhow::Result<()> { | ||
let new_store = Store::new()?; | ||
self.store = rdf_load( | ||
std::mem::replace(&mut self.store, new_store), | ||
&self.file_path, | ||
&self.base_iri, | ||
self.graph.as_ref(), | ||
) | ||
.await?; | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Analyze the ontology and give the documentation items to the | ||
/// given DocumentationModel. | ||
pub async fn analyze( | ||
&mut self, | ||
doc_model: &mut DocumentationModel, | ||
) -> anyhow::Result<()> { | ||
info!( | ||
"{}", | ||
style("Analyzing ontology...").green().bold() | ||
); | ||
self.load().await?; | ||
|
||
let mut documentable_items = Vec::new(); | ||
for quad_result in self.store.quads_for_pattern( | ||
None, | ||
None, | ||
None, | ||
Some(self.graph.as_ref()), | ||
) { | ||
match quad_result { | ||
Ok(quad) => { | ||
if self.is_documentable(&quad) { | ||
documentable_items.push(quad); | ||
} | ||
}, | ||
Err(e) => { | ||
error!( | ||
"{}: {}", | ||
style("Error processing quad").red().bold(), | ||
e | ||
); | ||
continue; | ||
}, | ||
} | ||
} | ||
// Store in documentation model | ||
for item in documentable_items { | ||
doc_model.add_documentable_item(item).await?; | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
fn is_documentable(&self, _quad: &Quad) -> bool { | ||
// TODO: Implement logic to determine if a | ||
// triple represents something we should | ||
// document For example: Classes, | ||
// Properties, Labels, Comments, etc. | ||
true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
mod rdf_load; | ||
mod tracing; | ||
|
||
pub use {rdf_load::rdf_load, tracing::setup_tracing}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
use { | ||
console::style, | ||
futures::TryStreamExt, | ||
oxigraph::store::Store, | ||
oxrdf::{GraphName, GraphNameRef}, | ||
oxrdfio::{RdfFormat, RdfParser}, | ||
reqwest::Client, | ||
std::path::Path, | ||
tokio::{fs::File as AsyncFile, io::AsyncReadExt, task}, | ||
tracing::info, | ||
url::Url, | ||
}; | ||
|
||
pub async fn rdf_load<'a>( | ||
mut store: Store, | ||
file_path: &String, | ||
base_iri: &String, | ||
graph: GraphNameRef<'a>, | ||
) -> anyhow::Result<Store> { | ||
info!( | ||
"{}", | ||
style("Loading ontology from source...").green().bold() | ||
); | ||
|
||
if let Ok(url) = Url::parse(&file_path) { | ||
// Handle URL | ||
let client = Client::new(); | ||
let response = client.get(url).send().await.map_err(|e| { | ||
anyhow::Error::new(e).context("Failed to send request") | ||
})?; | ||
if !response.status().is_success() { | ||
return Err(anyhow::Error::msg(format!( | ||
"Failed to fetch URL: {}", | ||
response.status() | ||
))); | ||
} | ||
let mut stream = response.bytes_stream().map_err(|e| { | ||
std::io::Error::new(std::io::ErrorKind::Other, e) | ||
}); | ||
let mut buffer = Vec::new(); | ||
while let Some(chunk) = stream.try_next().await? { | ||
buffer.extend_from_slice(&chunk); | ||
} | ||
|
||
let base_iri = base_iri.clone(); | ||
let graph = GraphName::from(graph); | ||
store = | ||
task::spawn_blocking(move || -> anyhow::Result<Store> { | ||
let reader = std::io::Cursor::new(buffer); | ||
store | ||
.load_from_reader( | ||
RdfParser::from_format(RdfFormat::Turtle) | ||
.with_base_iri(base_iri) | ||
.map_err(anyhow::Error::msg)? | ||
.without_named_graphs() | ||
.with_default_graph(graph), | ||
reader, | ||
) | ||
.map_err(anyhow::Error::msg)?; | ||
Ok(store) | ||
}) | ||
.await??; | ||
} else { | ||
// Handle file path | ||
let path = Path::new(&file_path); | ||
if !path.exists() { | ||
return Err(anyhow::Error::msg(format!( | ||
"File not found: {}", | ||
file_path | ||
))); | ||
} | ||
let mut file = AsyncFile::open(path).await?; | ||
let mut buffer = Vec::new(); | ||
file.read_to_end(&mut buffer).await?; | ||
|
||
let base_iri = base_iri.clone(); | ||
let graph = GraphName::from(graph); | ||
store = | ||
task::spawn_blocking(move || -> anyhow::Result<Store> { | ||
let reader = std::io::Cursor::new(buffer); | ||
store | ||
.load_from_reader( | ||
RdfParser::from_format(RdfFormat::Turtle) | ||
.with_base_iri(base_iri) | ||
.map_err(anyhow::Error::msg)? | ||
.without_named_graphs() | ||
.with_default_graph(graph), | ||
reader, | ||
) | ||
.map_err(anyhow::Error::msg)?; | ||
Ok(store) | ||
}) | ||
.await??; | ||
} | ||
|
||
info!( | ||
"{}", | ||
style("Ontology loaded successfully.").green().bold() | ||
); | ||
|
||
Ok(store) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
use tracing_subscriber::{EnvFilter, fmt}; | ||
|
||
/// Initialize tracing with custom format | ||
pub fn setup_tracing() -> anyhow::Result<()> { | ||
let env_filter = EnvFilter::try_from_default_env() | ||
.unwrap_or_else(|_| EnvFilter::new("info")); // Default to "info" if RUST_LOG is not set | ||
|
||
fmt() | ||
.with_env_filter(env_filter) | ||
.without_time() | ||
.with_target(false) | ||
.init(); | ||
|
||
Ok(()) | ||
} |