Fork of https://github.com/oxigraph/oxigraph.git for the purpose of NextGraph project
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
6.2 KiB
231 lines
6.2 KiB
use std::cmp::Ordering;
|
|
use std::error::Error;
|
|
use std::fmt;
|
|
|
|
/// A [SPARQL query](https://www.w3.org/TR/sparql11-query/) owned variable.
|
|
///
|
|
/// The default string formatter is returning a SPARQL compatible representation:
|
|
/// ```
|
|
/// use oxrdf::{Variable, VariableNameParseError};
|
|
///
|
|
/// assert_eq!(
|
|
/// "?foo",
|
|
/// Variable::new("foo")?.to_string()
|
|
/// );
|
|
/// # Result::<_,VariableNameParseError>::Ok(())
|
|
/// ```
|
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
|
|
pub struct Variable {
|
|
name: String,
|
|
}
|
|
|
|
impl Variable {
|
|
/// Creates a variable name from a unique identifier.
|
|
///
|
|
/// The variable identifier must be valid according to the SPARQL grammar.
|
|
pub fn new(name: impl Into<String>) -> Result<Self, VariableNameParseError> {
|
|
let name = name.into();
|
|
validate_variable_identifier(&name)?;
|
|
Ok(Self::new_unchecked(name))
|
|
}
|
|
|
|
/// Creates a variable name from a unique identifier without validation.
|
|
///
|
|
/// It is the caller's responsibility to ensure that `id` is a valid blank node identifier
|
|
/// according to the SPARQL grammar.
|
|
///
|
|
/// [`Variable::new()`] is a safe version of this constructor and should be used for untrusted data.
|
|
#[inline]
|
|
pub fn new_unchecked(name: impl Into<String>) -> Self {
|
|
Self { name: name.into() }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn as_str(&self) -> &str {
|
|
&self.name
|
|
}
|
|
|
|
#[inline]
|
|
pub fn into_string(self) -> String {
|
|
self.name
|
|
}
|
|
|
|
#[inline]
|
|
pub fn as_ref(&self) -> VariableRef<'_> {
|
|
VariableRef { name: &self.name }
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Variable {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
self.as_ref().fmt(f)
|
|
}
|
|
}
|
|
|
|
/// A [SPARQL query](https://www.w3.org/TR/sparql11-query/) borrowed variable.
|
|
///
|
|
/// The default string formatter is returning a SPARQL compatible representation:
|
|
/// ```
|
|
/// use oxrdf::{VariableRef, VariableNameParseError};
|
|
///
|
|
/// assert_eq!(
|
|
/// "?foo",
|
|
/// VariableRef::new("foo")?.to_string()
|
|
/// );
|
|
/// # Result::<_,VariableNameParseError>::Ok(())
|
|
/// ```
|
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)]
|
|
pub struct VariableRef<'a> {
|
|
name: &'a str,
|
|
}
|
|
|
|
impl<'a> VariableRef<'a> {
|
|
/// Creates a variable name from a unique identifier.
|
|
///
|
|
/// The variable identifier must be valid according to the SPARQL grammar.
|
|
pub fn new(name: &'a str) -> Result<Self, VariableNameParseError> {
|
|
validate_variable_identifier(name)?;
|
|
Ok(Self::new_unchecked(name))
|
|
}
|
|
|
|
/// Creates a variable name from a unique identifier without validation.
|
|
///
|
|
/// It is the caller's responsibility to ensure that `id` is a valid blank node identifier
|
|
/// according to the SPARQL grammar.
|
|
///
|
|
/// [`Variable::new()`] is a safe version of this constructor and should be used for untrusted data.
|
|
#[inline]
|
|
pub fn new_unchecked(name: &'a str) -> Self {
|
|
Self { name }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn as_str(&self) -> &str {
|
|
self.name
|
|
}
|
|
|
|
#[inline]
|
|
pub fn into_string(self) -> String {
|
|
self.name.to_owned()
|
|
}
|
|
|
|
#[inline]
|
|
pub fn into_owned(self) -> Variable {
|
|
Variable {
|
|
name: self.name.to_owned(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for VariableRef<'_> {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "?{}", self.name)
|
|
}
|
|
}
|
|
|
|
impl<'a> From<&'a Variable> for VariableRef<'a> {
|
|
#[inline]
|
|
fn from(variable: &'a Variable) -> Self {
|
|
variable.as_ref()
|
|
}
|
|
}
|
|
|
|
impl<'a> From<VariableRef<'a>> for Variable {
|
|
#[inline]
|
|
fn from(variable: VariableRef<'a>) -> Self {
|
|
variable.into_owned()
|
|
}
|
|
}
|
|
|
|
impl PartialEq<Variable> for VariableRef<'_> {
|
|
#[inline]
|
|
fn eq(&self, other: &Variable) -> bool {
|
|
*self == other.as_ref()
|
|
}
|
|
}
|
|
|
|
impl PartialEq<VariableRef<'_>> for Variable {
|
|
#[inline]
|
|
fn eq(&self, other: &VariableRef<'_>) -> bool {
|
|
self.as_ref() == *other
|
|
}
|
|
}
|
|
|
|
impl PartialOrd<Variable> for VariableRef<'_> {
|
|
#[inline]
|
|
fn partial_cmp(&self, other: &Variable) -> Option<Ordering> {
|
|
self.partial_cmp(&other.as_ref())
|
|
}
|
|
}
|
|
|
|
impl PartialOrd<VariableRef<'_>> for Variable {
|
|
#[inline]
|
|
fn partial_cmp(&self, other: &VariableRef<'_>) -> Option<Ordering> {
|
|
self.as_ref().partial_cmp(other)
|
|
}
|
|
}
|
|
|
|
fn validate_variable_identifier(id: &str) -> Result<(), VariableNameParseError> {
|
|
let mut chars = id.chars();
|
|
let front = chars.next().ok_or(VariableNameParseError {})?;
|
|
match front {
|
|
'0'..='9'
|
|
| '_'
|
|
| ':'
|
|
| 'A'..='Z'
|
|
| 'a'..='z'
|
|
| '\u{00C0}'..='\u{00D6}'
|
|
| '\u{00D8}'..='\u{00F6}'
|
|
| '\u{00F8}'..='\u{02FF}'
|
|
| '\u{0370}'..='\u{037D}'
|
|
| '\u{037F}'..='\u{1FFF}'
|
|
| '\u{200C}'..='\u{200D}'
|
|
| '\u{2070}'..='\u{218F}'
|
|
| '\u{2C00}'..='\u{2FEF}'
|
|
| '\u{3001}'..='\u{D7FF}'
|
|
| '\u{F900}'..='\u{FDCF}'
|
|
| '\u{FDF0}'..='\u{FFFD}'
|
|
| '\u{10000}'..='\u{EFFFF}' => (),
|
|
_ => return Err(VariableNameParseError {}),
|
|
}
|
|
for c in chars {
|
|
match c {
|
|
'0'..='9'
|
|
| '\u{00B7}'
|
|
| '\u{00300}'..='\u{036F}'
|
|
| '\u{203F}'..='\u{2040}'
|
|
| '_'
|
|
| 'A'..='Z'
|
|
| 'a'..='z'
|
|
| '\u{00C0}'..='\u{00D6}'
|
|
| '\u{00D8}'..='\u{00F6}'
|
|
| '\u{00F8}'..='\u{02FF}'
|
|
| '\u{0370}'..='\u{037D}'
|
|
| '\u{037F}'..='\u{1FFF}'
|
|
| '\u{200C}'..='\u{200D}'
|
|
| '\u{2070}'..='\u{218F}'
|
|
| '\u{2C00}'..='\u{2FEF}'
|
|
| '\u{3001}'..='\u{D7FF}'
|
|
| '\u{F900}'..='\u{FDCF}'
|
|
| '\u{FDF0}'..='\u{FFFD}'
|
|
| '\u{10000}'..='\u{EFFFF}' => (),
|
|
_ => return Err(VariableNameParseError {}),
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// An error raised during [`Variable`] name validation.
|
|
#[derive(Debug)]
|
|
pub struct VariableNameParseError {}
|
|
|
|
impl fmt::Display for VariableNameParseError {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "The variable name is invalid")
|
|
}
|
|
}
|
|
|
|
impl Error for VariableNameParseError {}
|
|
|