use super::evidence_types::{
CryptographicReceiptEvidencePayload, DiagnosticEvidencePayload, RangeEvidencePayload,
WorkspaceEvidencePayload,
};
pub fn extract_workspaces_from_store(
store: &oxigraph::store::Store,
graph_name: &oxigraph::model::GraphName,
) -> Result<Vec<WorkspaceEvidencePayload>, String> {
let rdf_type =
oxigraph::model::NamedNode::new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").unwrap();
let project_type = oxigraph::model::Term::NamedNode(
oxigraph::model::NamedNode::new("https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/Project").unwrap()
);
let doc_type = oxigraph::model::Term::NamedNode(
oxigraph::model::NamedNode::new("https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/Document").unwrap()
);
let uri_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:uri").unwrap();
let mut document_uris = Vec::new();
for quad in store.quads_for_pattern(
None,
Some(rdf_type.as_ref()),
Some(doc_type.as_ref()),
Some(graph_name.as_ref()),
) {
let quad = quad.map_err(|e| e.to_string())?;
for uri_quad in store.quads_for_pattern(
Some(quad.subject.as_ref()),
Some(uri_pred.as_ref()),
None,
Some(graph_name.as_ref()),
) {
let uri_quad = uri_quad.map_err(|e| e.to_string())?;
if let oxigraph::model::Term::Literal(lit) = uri_quad.object {
document_uris.push(lit.value().to_string());
}
}
}
let mut workspaces = Vec::new();
for quad in store.quads_for_pattern(
None,
Some(rdf_type.as_ref()),
Some(project_type.as_ref()),
Some(graph_name.as_ref()),
) {
let quad = quad.map_err(|e| e.to_string())?;
workspaces.push(WorkspaceEvidencePayload {
id: quad.subject.to_string(),
kind: "Project".to_string(),
document_uris: document_uris.clone(),
});
}
if workspaces.is_empty() && !document_uris.is_empty() {
workspaces.push(WorkspaceEvidencePayload {
id: "urn:lsp-max:workspace:default".to_string(),
kind: "Workspace".to_string(),
document_uris,
});
}
Ok(workspaces)
}
pub fn extract_ranges_from_store(
store: &oxigraph::store::Store,
graph_name: &oxigraph::model::GraphName,
) -> Result<Vec<RangeEvidencePayload>, String> {
let rdf_type =
oxigraph::model::NamedNode::new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").unwrap();
let range_type = oxigraph::model::Term::NamedNode(
oxigraph::model::NamedNode::new("https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/Range").unwrap()
);
fn lit_u32(
store: &oxigraph::store::Store,
subject: oxigraph::model::NamedOrBlankNodeRef,
pred: &oxigraph::model::NamedNode,
graph: &oxigraph::model::GraphName,
) -> u32 {
store
.quads_for_pattern(
Some(subject),
Some(pred.as_ref()),
None,
Some(graph.as_ref()),
)
.flatten()
.find_map(|q| {
if let oxigraph::model::Term::Literal(l) = q.object {
l.value().parse().ok()
} else {
None
}
})
.unwrap_or(0)
}
let sl = oxigraph::model::NamedNode::new("urn:lsp-max:range:startLine").unwrap();
let sc = oxigraph::model::NamedNode::new("urn:lsp-max:range:startCharacter").unwrap();
let el = oxigraph::model::NamedNode::new("urn:lsp-max:range:endLine").unwrap();
let ec = oxigraph::model::NamedNode::new("urn:lsp-max:range:endCharacter").unwrap();
let mut ranges = Vec::new();
for quad in store.quads_for_pattern(
None,
Some(rdf_type.as_ref()),
Some(range_type.as_ref()),
Some(graph_name.as_ref()),
) {
let quad = quad.map_err(|e| e.to_string())?;
let subj = quad.subject.as_ref();
ranges.push(RangeEvidencePayload {
start_line: lit_u32(store, subj, &sl, graph_name),
start_character: lit_u32(store, subj, &sc, graph_name),
end_line: lit_u32(store, subj, &el, graph_name),
end_character: lit_u32(store, subj, &ec, graph_name),
});
}
Ok(ranges)
}
pub fn extract_diagnostics_from_store(
store: &oxigraph::store::Store,
graph_name: &oxigraph::model::GraphName,
) -> Result<Vec<DiagnosticEvidencePayload>, String> {
let rdf_type =
oxigraph::model::NamedNode::new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").unwrap();
let diag_type = oxigraph::model::Term::NamedNode(
oxigraph::model::NamedNode::new("urn:lsp-max:core:Diagnostic").unwrap(),
);
let msg_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:message").unwrap();
let sev_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:severity").unwrap();
let code_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:code").unwrap();
let source_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:source").unwrap();
fn lit_str(
store: &oxigraph::store::Store,
subject: oxigraph::model::NamedOrBlankNodeRef,
pred: &oxigraph::model::NamedNode,
graph: &oxigraph::model::GraphName,
) -> Option<String> {
store
.quads_for_pattern(
Some(subject),
Some(pred.as_ref()),
None,
Some(graph.as_ref()),
)
.flatten()
.find_map(|q| {
if let oxigraph::model::Term::Literal(l) = q.object {
Some(l.value().to_string())
} else {
None
}
})
}
let mut diagnostics = Vec::new();
for quad in store.quads_for_pattern(
None,
Some(rdf_type.as_ref()),
Some(diag_type.as_ref()),
Some(graph_name.as_ref()),
) {
let quad = quad.map_err(|e| e.to_string())?;
let subj = quad.subject.as_ref();
diagnostics.push(DiagnosticEvidencePayload {
message: lit_str(store, subj, &msg_pred, graph_name).unwrap_or_default(),
severity: lit_str(store, subj, &sev_pred, graph_name),
code: lit_str(store, subj, &code_pred, graph_name),
source: lit_str(store, subj, &source_pred, graph_name),
range: None,
});
}
Ok(diagnostics)
}
pub fn extract_receipts_from_store(
store: &oxigraph::store::Store,
graph_name: &oxigraph::model::GraphName,
) -> Result<Vec<CryptographicReceiptEvidencePayload>, String> {
let rdf_type =
oxigraph::model::NamedNode::new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").unwrap();
let rcpt_type = oxigraph::model::Term::NamedNode(
oxigraph::model::NamedNode::new("urn:lsp-max:core:Receipt").unwrap(),
);
let prev_hash_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:prevHash").unwrap();
let result_hash_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:resultHash").unwrap();
let query_hash_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:queryHash").unwrap();
let graph_hash_pred = oxigraph::model::NamedNode::new("urn:lsp-max:core:graphHash").unwrap();
fn lit_str(
store: &oxigraph::store::Store,
subject: oxigraph::model::NamedOrBlankNodeRef,
pred: &oxigraph::model::NamedNode,
graph: &oxigraph::model::GraphName,
) -> String {
store
.quads_for_pattern(
Some(subject),
Some(pred.as_ref()),
None,
Some(graph.as_ref()),
)
.flatten()
.find_map(|q| {
if let oxigraph::model::Term::Literal(l) = q.object {
Some(l.value().to_string())
} else {
None
}
})
.unwrap_or_default()
}
let mut receipts = Vec::new();
for quad in store.quads_for_pattern(
None,
Some(rdf_type.as_ref()),
Some(rcpt_type.as_ref()),
Some(graph_name.as_ref()),
) {
let quad = quad.map_err(|e| e.to_string())?;
let subj = quad.subject.as_ref();
receipts.push(CryptographicReceiptEvidencePayload {
prev_hash: lit_str(store, subj, &prev_hash_pred, graph_name),
consequence_hash: lit_str(store, subj, &result_hash_pred, graph_name),
law_id: lit_str(store, subj, &query_hash_pred, graph_name),
discipline_id: lit_str(store, subj, &graph_hash_pred, graph_name),
sequence: 0,
signature: String::new(),
});
}
Ok(receipts)
}