use oxigraph::sparql::SparqlEvaluator;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SparqlKind {
Select,
Construct,
Ask,
Describe,
Unknown,
}
#[must_use]
pub fn sparql_kind(query: &str) -> SparqlKind {
for raw in query.lines() {
let line = raw.trim();
if line.is_empty() || line.starts_with('#') {
continue;
}
let upper = line.to_ascii_uppercase();
if upper.starts_with("PREFIX") || upper.starts_with("BASE") {
continue;
}
if upper.starts_with("SELECT") {
return SparqlKind::Select;
} else if upper.starts_with("CONSTRUCT") {
return SparqlKind::Construct;
} else if upper.starts_with("ASK") {
return SparqlKind::Ask;
} else if upper.starts_with("DESCRIBE") {
return SparqlKind::Describe;
}
break;
}
let upper = query.to_ascii_uppercase();
if upper.contains("SELECT") {
SparqlKind::Select
} else if upper.contains("CONSTRUCT") {
SparqlKind::Construct
} else if upper.contains("ASK") {
SparqlKind::Ask
} else if upper.contains("DESCRIBE") {
SparqlKind::Describe
} else {
SparqlKind::Unknown
}
}
pub fn check_sparql_syntax(query: &str) -> Result<(), String> {
SparqlEvaluator::new()
.parse_query(query)
.map(|_| ())
.map_err(|e| e.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn detects_query_forms() {
assert_eq!(
sparql_kind("PREFIX ex: <http://e/>\nSELECT ?s WHERE { ?s ?p ?o }"),
SparqlKind::Select
);
assert_eq!(sparql_kind("ASK { ?s ?p ?o }"), SparqlKind::Ask);
assert_eq!(
sparql_kind("CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }"),
SparqlKind::Construct
);
}
#[test]
fn valid_query_passes_syntax_check() {
assert!(check_sparql_syntax("SELECT ?s WHERE { ?s ?p ?o }").is_ok());
}
#[test]
fn invalid_query_fails_syntax_check() {
assert!(check_sparql_syntax("SELECT WHERE {{{").is_err());
}
}