rudof_rdf/rdf_core/query/var_name.rs
1use crate::rdf_core::{
2 Rdf,
3 query::{QuerySolution, VariableSolutionIndex},
4};
5use serde::Serialize;
6use std::fmt::Display;
7
8/// Represents a SPARQL variable name without the `?` or `$` prefix.
9///
10/// In SPARQL queries, variables are identifiers that begin with `?` or `$` (e.g.,
11/// `?person`, `$email`). This type stores the variable name without the prefix,
12/// but displays it with `?` when formatted.
13#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize)]
14pub struct VarName {
15 /// The variable name string without prefix.
16 str: String,
17}
18
19impl VarName {
20 /// Creates a new variable name from a string.
21 ///
22 /// # Arguments
23 ///
24 /// * `str` - The variable name without prefix
25 pub fn new(str: &str) -> VarName {
26 VarName { str: str.to_string() }
27 }
28
29 /// Returns the variable name as a string slice without prefix.
30 pub fn as_str(&self) -> &str {
31 &self.str
32 }
33}
34
35impl Display for VarName {
36 /// Formats the variable name with the SPARQL `?` prefix.
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 write!(f, "?{}", self.str)
39 }
40}
41
42impl From<String> for VarName {
43 /// Converts a `String` into a `VarName`.
44 ///
45 /// This conversion takes ownership of the string and wraps it as a variable
46 /// name. The input should be the variable name without the `?` or `$` prefix.
47 ///
48 /// # Arguments
49 ///
50 /// * `value` - The string to convert (without prefix)
51 fn from(value: String) -> Self {
52 VarName { str: value }
53 }
54}
55
56impl<S: Rdf> VariableSolutionIndex<S> for &VarName {
57 /// Finds the index of this variable in a query solution.
58 ///
59 /// This implementation allows `&VarName` to be used for looking up variable
60 /// positions within a [`QuerySolution`]. The variable is matched by comparing
61 /// the stored name string with variable names in the solution.
62 ///
63 /// # Arguments
64 ///
65 /// * `solution` - The query solution to search for this variable
66 fn index(self, solution: &QuerySolution<S>) -> Option<usize> {
67 solution.variables_iter().position(|v| *v.str == self.str)
68 }
69}