Skip to main content

rudof_rdf/rdf_core/parser/
rdf_parser.rs

1use crate::rdf_core::{
2    FocusRDF, RDFError,
3    parser::rdf_node_parser::{
4        RDFNodeParse,
5        constructors::{
6            HasTypeParser, InstancesParser, ListParser, SatisfyParser, SingleInstanceParser, SingleValuePropertyParser,
7            TypeParser, ValuesPropertyParser,
8        },
9    },
10};
11use iri_s::IriS;
12use prefixmap::PrefixMap;
13use std::collections::HashSet;
14
15/// Execution context for RDF parsing operations.
16///
17/// Holds the RDF graph and provides methods to execute parsers against it.
18/// Automatically handles focus management and provides conveniences for
19/// common RDF access patterns (properties, lists, type checking).
20pub struct RDFParse<RDF>
21where
22    RDF: FocusRDF,
23{
24    /// The underlying RDF graph
25    rdf: RDF,
26
27    /// Optional: track original focus for restoration (if needed)
28    initial_focus: Option<RDF::Term>,
29}
30
31impl<RDF> RDFParse<RDF>
32where
33    RDF: FocusRDF,
34{
35    /// Creates a new parsing context wrapping the RDF graph.
36    pub fn new(rdf: RDF) -> Self {
37        Self {
38            rdf,
39            initial_focus: None,
40        }
41    }
42
43    /// Creates a context and immediately sets the focus to the given IRI.
44    pub fn with_focus(rdf: RDF, focus_iri: &IriS) -> Self {
45        let mut ctx = Self::new(rdf);
46        ctx.set_focus_iri(focus_iri);
47        ctx
48    }
49
50    // ============================================================================
51    // Basic accessors
52    // ============================================================================
53
54    /// Returns the prefix map of the underlying graph.
55    pub fn prefixmap(&self) -> Option<PrefixMap> {
56        self.rdf.prefixmap()
57    }
58
59    /// Gets the current focus node, if set.
60    pub fn current_focus(&self) -> Option<&RDF::Term> {
61        self.rdf.get_focus()
62    }
63
64    /// Sets the focus node to a specific term.
65    pub fn set_focus(&mut self, focus: &RDF::Term) {
66        // Store initial focus on first mutation for potential restoration
67        if self.initial_focus.is_none() {
68            self.initial_focus = self.rdf.get_focus().cloned();
69        }
70        self.rdf.set_focus(focus);
71    }
72
73    /// Sets the focus node from an IRI.
74    pub fn set_focus_iri(&mut self, iri: &IriS) {
75        let term: RDF::Term = iri.clone().into();
76        self.set_focus(&term);
77    }
78
79    /// Restores the focus to the initial focus when the context was created.
80    pub fn restore_focus(&mut self) {
81        if let Some(ref initial) = self.initial_focus {
82            self.rdf.set_focus(initial);
83        }
84    }
85
86    /// Returns a reference to the underlying RDF graph.
87    pub fn rdf(&self) -> &RDF {
88        &self.rdf
89    }
90
91    pub fn rdf_mut(&mut self) -> &mut RDF {
92        &mut self.rdf
93    }
94
95    // ============================================================================
96    // Generic execution (core)
97    // ============================================================================
98
99    /// Executes any parser against the current context.
100    ///
101    /// This is the universal entry point - accepts any parser implementing
102    /// `RDFNodeParse`, from simple property extractors to complex compositions.
103    ///
104    /// # Type Parameters
105    /// * `P` - The parser type
106    /// * `T` - The output type of the parser
107    pub fn run<P, T>(&mut self, parser: P) -> Result<T, RDFError>
108    where
109        P: RDFNodeParse<RDF, Output = T>,
110    {
111        parser.parse_focused(&mut self.rdf)
112    }
113
114    /// Executes a parser starting from a specific node (ignores current focus).
115    ///
116    /// Temporarily sets focus to `start_node`, executes the parser, then
117    /// restores the previous focus.
118    pub fn run_from<P, T>(&mut self, start_node: &IriS, parser: P) -> Result<T, RDFError>
119    where
120        P: RDFNodeParse<RDF, Output = T>,
121    {
122        let previous = self.rdf.get_focus().cloned();
123        let term: RDF::Term = start_node.clone().into();
124        self.rdf.set_focus(&term);
125
126        let result = parser.parse_focused(&mut self.rdf);
127
128        // Restore previous focus
129        if let Some(prev) = previous {
130            self.rdf.set_focus(&prev);
131        }
132
133        result
134    }
135
136    // ============================================================================
137    // Convenience methods (wrappers around common constructors)
138    // ============================================================================
139
140    /// Gets all values of a property from the current focus node.
141    ///
142    /// Equivalent to `ctx.run(ValuesPropertyParser::new(pred))`.
143    pub fn get_property_values(&mut self, pred: IriS) -> Result<HashSet<RDF::Term>, RDFError> {
144        ValuesPropertyParser::new(pred).parse_focused(&mut self.rdf)
145    }
146
147    /// Gets a single value of a property.
148    pub fn get_property(&mut self, pred: IriS) -> Result<RDF::Term, RDFError> {
149        SingleValuePropertyParser::new(pred).parse_focused(&mut self.rdf)
150    }
151
152    /// Gets the `rdf:type` of the current focus node.
153    pub fn get_type(&mut self) -> Result<RDF::Term, RDFError> {
154        TypeParser::new().parse_focused(&mut self.rdf)
155    }
156
157    /// Checks if the current focus has the given type.
158    pub fn has_type(&mut self, expected: IriS) -> Result<(), RDFError> {
159        HasTypeParser::new(expected).parse_focused(&mut self.rdf)
160    }
161
162    /// Parses an RDF list starting at the current focus.
163    pub fn parse_list(&mut self) -> Result<Vec<RDF::Term>, RDFError>
164    where
165        RDF: FocusRDF,
166    {
167        ListParser::new().parse_focused(&mut self.rdf)
168    }
169
170    /// Parses an RDF list pointed to by a property.
171    pub fn get_list_property(&mut self, pred: IriS) -> Result<Vec<RDF::Term>, RDFError>
172    where
173        RDF: FocusRDF,
174    {
175        let head = self.get_property(pred)?;
176        self.rdf.set_focus(&head);
177        ListParser::new().parse_focused(&mut self.rdf)
178    }
179
180    // ============================================================================
181    // Graph-wide queries
182    // ============================================================================
183
184    /// Finds all instances of a given type in the entire graph.
185    ///
186    /// This is a graph-wide query, not focus-dependent.
187    pub fn find_instances_of(&mut self, type_iri: IriS) -> Result<Vec<RDF::Subject>, RDFError>
188    where
189        RDF: FocusRDF,
190    {
191        // Store current focus to restore later
192        let saved_focus = self.rdf.get_focus().cloned();
193
194        // Execute type-based finder
195        let result = InstancesParser::new(type_iri).parse_focused(&mut self.rdf);
196
197        // Restore focus
198        if let Some(focus) = saved_focus {
199            self.rdf.set_focus(&focus);
200        }
201
202        result
203    }
204
205    /// Finds exactly one instance of a type (fails if not exactly one).
206    pub fn find_single_instance(&mut self, type_iri: IriS) -> Result<RDF::Subject, RDFError>
207    where
208        RDF: FocusRDF,
209    {
210        let saved_focus = self.rdf.get_focus().cloned();
211        let result = SingleInstanceParser::new(type_iri).parse_focused(&mut self.rdf);
212
213        if let Some(focus) = saved_focus {
214            self.rdf.set_focus(&focus);
215        }
216
217        result
218    }
219
220    /// Validates current focus against a predicate.
221    pub fn check<F>(&mut self, predicate: F, name: &str) -> Result<(), RDFError>
222    where
223        F: Fn(&RDF::Term) -> bool,
224    {
225        SatisfyParser::new(predicate, name).parse_focused(&mut self.rdf)
226    }
227}