oak_core/helpers/
mod.rs

1//! Helper utilities for common operations in the Oak Core parsing framework.
2//!
3//! This module provides utility functions for file system operations, URL handling,
4//! and other common tasks that are useful when working with the parsing framework.
5
6use crate::errors::OakError;
7
8use crate::{SourceLocation, SourceText};
9
10use std::fs::File;
11
12use url::Url;
13#[cfg(feature = "testing")]
14mod lexing;
15#[cfg(feature = "testing")]
16pub use self::lexing::LexerTester;
17
18#[cfg(feature = "testing")]
19mod parsing;
20#[cfg(feature = "testing")]
21pub use self::parsing::ParserTester;
22
23/// Converts a file system path to a URL.
24///
25/// # Arguments
26///
27/// * `path` - The file system path to convert
28///
29/// # Returns
30///
31/// A `Result` containing the URL if successful, or an `OakError` if the path is invalid
32///
33/// # Examples
34///
35/// ```ignore
36/// let path = std::path::Path::new("/home/user/file.txt");
37/// let url = url_from_path(path)?;
38/// ```
39pub fn url_from_path(path: &std::path::Path) -> Result<Url, OakError> {
40    match Url::from_file_path(path) {
41        Ok(o) => Ok(o),
42        Err(_) => Err(OakError::syntax_error(format!("invalid url {}", path.display()), SourceLocation::default())),
43    }
44}
45
46/// Reads source text from a file path.
47///
48/// This function reads the contents of a file and creates a `SourceText` with
49/// the appropriate URL metadata. It's a convenience function for loading source
50/// files into the parsing system.
51///
52/// # Arguments
53///
54/// * `path` - The file system path to read from
55///
56/// # Returns
57///
58/// A `Result` containing the `SourceText` if successful, or an `OakError` if reading fails
59///
60/// # Examples
61///
62/// ```ignore
63/// let path = std::path::Path::new("source.rs");
64/// let source = source_from_path(path)?;
65/// ```
66pub fn source_from_path(path: &std::path::Path) -> Result<SourceText, OakError> {
67    let url = url_from_path(path)?;
68    match std::fs::read_to_string(path) {
69        Ok(o) => Ok(SourceText::new_with_url(o, url)),
70        Err(e) => Err(OakError::io_error(e, url)),
71    }
72}
73
74/// Reads JSON data from a file path.
75///
76/// This function reads the contents of a file and parses it as JSON.
77///
78/// # Arguments
79///
80/// * `path`: The file system path to read from
81///
82/// returns: Result<T, OakError>
83///
84/// # Examples
85///
86/// ```
87/// ```
88#[cfg(feature = "serde_json")]
89pub fn json_from_path<T>(path: &std::path::Path) -> Result<T, OakError>
90where
91    T: for<'de> serde::Deserialize<'de>,
92{
93    let url = url_from_path(path)?;
94    match File::open(path) {
95        Ok(o) => Ok(serde_json::from_reader(o)?),
96        Err(e) => Err(OakError::io_error(e, url)),
97    }
98}
99
100/// Opens a file and returns a file handle.
101///
102/// # Arguments
103///
104/// * `path` - The file system path to open
105///
106/// # Returns
107///
108/// A `Result` containing the file handle if successful, or an `OakError` if opening fails
109///
110/// # Examples
111///
112/// ```ignore
113/// let path = std::path::Path::new("source.rs");
114/// let file = open_file(path)?;
115/// ```
116pub fn open_file(path: &std::path::Path) -> Result<File, OakError> {
117    let url = url_from_path(path)?;
118    match File::open(path) {
119        Ok(o) => Ok(o),
120        Err(e) => Err(OakError::io_error(e, url)),
121    }
122}
123
124/// Creates a file and returns a file handle.
125///
126/// # Arguments
127///
128/// * `path` - The file system path to create
129///
130/// # Returns
131///
132/// A `Result` containing the file handle if successful, or an `OakError` if creation fails
133///
134/// # Examples
135///
136/// ```ignore
137/// let path = std::path::Path::new("output.txt");
138/// let file = create_file(path)?;
139/// ```
140pub fn create_file(path: &std::path::Path) -> Result<File, OakError> {
141    let url = url_from_path(path)?;
142    match File::create(path) {
143        Ok(o) => Ok(o),
144        Err(e) => Err(OakError::io_error(e, url)),
145    }
146}