Docs
This commit is contained in:
parent
ac8862e459
commit
347fd6ce59
8 changed files with 65 additions and 27 deletions
4
src/cache/cache.rs
vendored
4
src/cache/cache.rs
vendored
|
@ -33,9 +33,9 @@ pub trait Cached {
|
|||
/// # Error
|
||||
///
|
||||
/// Will return an error if the database connection(s) fail,
|
||||
/// or if not cached, an error from the generator [`f`]
|
||||
/// or if not cached, an error from the generator `f`
|
||||
///
|
||||
/// Note that on error, [`f`] may still have been called
|
||||
/// Note that on error, `f` may still have been called
|
||||
fn cached<E, F>(
|
||||
&self,
|
||||
con: &Connection,
|
||||
|
|
|
@ -300,7 +300,7 @@ pub struct CompiledDocument {
|
|||
pub variables: HashMap<String, String>,
|
||||
|
||||
/// All the referenceable elements in the document
|
||||
/// with values mapped by [`ReferenceableElement::refid()`]
|
||||
/// with values mapped by [`crate::document::element::ReferenceableElement::refid()`]
|
||||
pub references: HashMap<String, String>,
|
||||
|
||||
/// Compiled document's header
|
||||
|
|
|
@ -177,11 +177,11 @@ pub trait Document<'a>: core::fmt::Debug {
|
|||
}
|
||||
}
|
||||
|
||||
/// Merges [`other`] into [`self`]
|
||||
/// Merges another [`Document`]'s scope into [`self`]
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// If [`merge_as`] is None, references and variables from the other document are not merged into self
|
||||
/// If `merge_as` is None, references and variables from the other document are not merged into self
|
||||
fn merge(
|
||||
&self,
|
||||
content: &RefCell<Vec<Box<dyn Element>>>,
|
||||
|
|
|
@ -180,7 +180,7 @@ impl<'a, 'b> ParserState<'a, 'b> {
|
|||
/// 2. (Optional) The winning match with it's match data
|
||||
/// If the winning match is None, it means that the document has no more
|
||||
/// rule to match. I.e The rest of the content should be added as a
|
||||
/// [`Text`] element.
|
||||
/// [`crate::elements::text::Text`] element.
|
||||
/// The match data should be passed to the [`Rule::on_match`] method.
|
||||
///
|
||||
/// # Strategy
|
||||
|
@ -298,13 +298,13 @@ impl<'a, 'b> ParserState<'a, 'b> {
|
|||
}
|
||||
|
||||
/// Resets the position and the match_data for a given rule. This is used
|
||||
/// in order to have 'dynamic' rules that may not match at first, but their
|
||||
/// matching rule is modified through the parsing process.
|
||||
/// in order to have 'dynamic' rules that may not match at first, but may match
|
||||
/// in the future when modified.
|
||||
///
|
||||
/// This function also recursively calls itself on it's `parent`, in order
|
||||
/// to fully reset the match.
|
||||
///
|
||||
/// See [`CustomStyleRule`] for an example of how this is used.
|
||||
/// See [`crate::elements::customstyle::CustomStyleRule`] for an example of how this is used.
|
||||
///
|
||||
/// # Error
|
||||
///
|
||||
|
|
|
@ -70,7 +70,7 @@ pub trait Rule: Downcast {
|
|||
/// The name of the rule that should come before this one
|
||||
fn previous(&self) -> Option<&'static str>;
|
||||
|
||||
/// Finds the next match starting from [`cursor`]
|
||||
/// Finds the next match starting from `cursor`
|
||||
fn next_match(
|
||||
&self,
|
||||
mode: &ParseMode,
|
||||
|
@ -137,7 +137,7 @@ impl<T: RegexRule + 'static> Rule for T {
|
|||
|
||||
fn previous(&self) -> Option<&'static str> { RegexRule::previous(self) }
|
||||
|
||||
/// Finds the next match starting from [`cursor`]
|
||||
/// Finds the next match starting from [`Cursor`]
|
||||
fn next_match(
|
||||
&self,
|
||||
mode: &ParseMode,
|
||||
|
|
|
@ -10,8 +10,13 @@ use unicode_segmentation::UnicodeSegmentation;
|
|||
/// Trait for source content
|
||||
pub trait Source: Downcast + Debug {
|
||||
/// Gets the source's location
|
||||
///
|
||||
/// This usually means the parent source.
|
||||
/// If the source is a [`SourceFile`], this generally means the [`SourceFile`] that included it.
|
||||
fn location(&self) -> Option<&Token>;
|
||||
/// Gets the source's name
|
||||
///
|
||||
/// For [`SourceFile`] this means the path of the source. Note that some [`VirtualSource`] are prefixed with a special identifier such as `:LUA:`.
|
||||
fn name(&self) -> &String;
|
||||
/// Gets the source's content
|
||||
fn content(&self) -> &String;
|
||||
|
@ -37,13 +42,19 @@ impl std::hash::Hash for dyn Source {
|
|||
/// [`SourceFile`] is a type of [`Source`] that represents a real file.
|
||||
#[derive(Debug)]
|
||||
pub struct SourceFile {
|
||||
/// The token that created this [`SourceFile`], empty if file comes from the executable's
|
||||
/// options.
|
||||
location: Option<Token>,
|
||||
/// Path to the file, used for the [`Self::name()`] method
|
||||
path: String,
|
||||
/// Content of the file
|
||||
content: String,
|
||||
}
|
||||
|
||||
impl SourceFile {
|
||||
// TODO: Create a SourceFileRegistry holding already loaded files to avoid reloading them
|
||||
/// Creates a [`SourceFile`] from a `path`. This will read the content of the file at that
|
||||
/// `path`. In case the file is not accessible or reading fails, an error is returned.
|
||||
pub fn new(path: String, location: Option<Token>) -> Result<Self, String> {
|
||||
match fs::read_to_string(&path) {
|
||||
Err(_) => Err(format!("Unable to read file content: `{}`", path)),
|
||||
|
@ -55,6 +66,7 @@ impl SourceFile {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a [`SourceFile`] from a `String`
|
||||
pub fn with_content(path: String, content: String, location: Option<Token>) -> Self {
|
||||
Self {
|
||||
location,
|
||||
|
@ -63,6 +75,7 @@ impl SourceFile {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the path of this [`SourceFile`]
|
||||
pub fn path(&self) -> &String { &self.path }
|
||||
}
|
||||
|
||||
|
@ -79,8 +92,8 @@ impl Source for SourceFile {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Let's say you make a virtual source from the following: "Con\]tent" -> "Con]tent"
|
||||
/// Then at position 3, an offset of 1 will be created to account for the removed '\'
|
||||
/// Let's say you make a virtual source from the following: "Con\\]tent" -> "Con]tent"
|
||||
/// Then at position 3, an offset of 1 will be created to account for the removed '\\'
|
||||
#[derive(Debug)]
|
||||
struct SourceOffset {
|
||||
/// Stores the total offsets
|
||||
|
@ -105,16 +118,25 @@ impl SourceOffset {
|
|||
|
||||
/// [`VirtualSource`] is a type of [`Source`] that represents a virtual file. [`VirtualSource`]s
|
||||
/// can be created from other [`VirtualSource`]s but it must always come from a [`SourceFile`].
|
||||
///
|
||||
/// # Offsets
|
||||
///
|
||||
/// [`VirtualSource`] will keep a list of offsets that were applied from the their parent source (available via [`Self::location`]).
|
||||
/// For instance, if you consider the [`VirtualSource`] created by removing the '\\' from the following string: "He\\llo", then an offset is stored to account for the missing '\\'. This is required in order to keep diagnostics accurate.
|
||||
#[derive(Debug)]
|
||||
pub struct VirtualSource {
|
||||
/// Token that createrd this [`VirtualSource`]
|
||||
location: Token,
|
||||
/// Name of the [`VirtualSource`]
|
||||
name: String,
|
||||
/// Content of the [`VirtualSource`]
|
||||
content: String,
|
||||
/// Offset relative to the [`location`]'s source
|
||||
/// Offsets relative to the [`Self::location`]'s source
|
||||
offsets: Option<SourceOffset>,
|
||||
}
|
||||
|
||||
impl VirtualSource {
|
||||
/// Creates a new [`VirtualSource`] from a `location`, `name` and `content`.
|
||||
pub fn new(location: Token, name: String, content: String) -> Self {
|
||||
Self {
|
||||
location,
|
||||
|
@ -124,6 +146,11 @@ impl VirtualSource {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new [`VirtualSource`] from a `location`, `name`, `content` and `offsets`.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// This should be called by [`crate::parser::util::escape_source`]
|
||||
pub fn new_offsets(
|
||||
location: Token,
|
||||
name: String,
|
||||
|
@ -233,7 +260,7 @@ pub struct Cursor {
|
|||
impl Cursor {
|
||||
pub fn new(pos: usize, source: Rc<dyn Source>) -> Self { Self { pos, source } }
|
||||
|
||||
/// Creates [`cursor`] at [`new_pos`] in the same [`file`]
|
||||
/// Creates [`Cursor`] at `new_pos` in the same [`Source`]
|
||||
pub fn at(&self, new_pos: usize) -> Self {
|
||||
Self {
|
||||
pos: new_pos,
|
||||
|
@ -246,7 +273,7 @@ impl Cursor {
|
|||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// Because the LSP uses UTF-16 encoded positions, field [`line_pos`] corresponds to the UTF-16
|
||||
/// Because the LSP uses UTF-16 encoded positions, field [`Self::line_pos`] corresponds to the UTF-16
|
||||
/// distance between the first character (position = 0 or after '\n') and the character at the
|
||||
/// current position.
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -273,10 +300,11 @@ impl LineCursor {
|
|||
}
|
||||
|
||||
/// Moves [`LineCursor`] to an absolute byte position
|
||||
/// This function may only advance the position, as is required for the LSP semantics.
|
||||
///
|
||||
/// # Error
|
||||
///
|
||||
/// This function will panic if [`pos`] is not utf8 aligned
|
||||
/// This function will panic if [`Self::pos`] is not UTF-88 aligned, or if trying to go to a previous position.
|
||||
pub fn move_to(&mut self, pos: usize) {
|
||||
if self.pos < pos {
|
||||
let start = self.pos;
|
||||
|
|
|
@ -5,18 +5,20 @@ use downcast_rs::impl_downcast;
|
|||
use downcast_rs::Downcast;
|
||||
|
||||
/// Styling for an element
|
||||
///
|
||||
/// Some elements have support for styling.
|
||||
pub trait ElementStyle: Downcast + core::fmt::Debug {
|
||||
/// The style key
|
||||
fn key(&self) -> &'static str;
|
||||
|
||||
/// Attempts to create a new style from a [`json`] string
|
||||
/// Attempts to create a new style from a `json` string
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will fail if deserialization fails
|
||||
fn from_json(&self, json: &str) -> Result<Rc<dyn ElementStyle>, String>;
|
||||
|
||||
/// Attempts to deserialize lua table into a new style
|
||||
/// Attempts to deserialize a `lua table` into a new style
|
||||
fn from_lua(
|
||||
&self,
|
||||
lua: &mlua::Lua,
|
||||
|
@ -25,6 +27,7 @@ pub trait ElementStyle: Downcast + core::fmt::Debug {
|
|||
}
|
||||
impl_downcast!(ElementStyle);
|
||||
|
||||
/// A structure that holds registered [`ElementStyle`]
|
||||
#[derive(Default)]
|
||||
pub struct StyleHolder {
|
||||
styles: HashMap<String, Rc<dyn ElementStyle>>,
|
||||
|
@ -35,13 +38,17 @@ impl StyleHolder {
|
|||
pub fn is_registered(&self, style_key: &str) -> bool { self.styles.contains_key(style_key) }
|
||||
|
||||
/// Gets the current active style for an element
|
||||
/// NOTE: Will panic if a style is not defined for a given element
|
||||
/// If you need to process user input, use [`is_registered`]
|
||||
/// If you need to process user input, use [`Self::is_registered`]
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// Will panic if a style is not defined for a given element.
|
||||
/// Elements should have their styles (when they support it) registered when the parser starts.
|
||||
pub fn current(&self, style_key: &str) -> Rc<dyn ElementStyle> {
|
||||
self.styles.get(style_key).cloned().unwrap()
|
||||
}
|
||||
|
||||
/// Sets the [`style`]
|
||||
/// Sets the style
|
||||
pub fn set_current(&mut self, style: Rc<dyn ElementStyle>) {
|
||||
self.styles.insert(style.key().to_string(), style);
|
||||
}
|
||||
|
|
|
@ -90,12 +90,15 @@ pub fn process_text(document: &dyn Document, content: &str) -> String {
|
|||
processed
|
||||
}
|
||||
|
||||
/// Transforms source into a new [`VirtualSource`]. Transforms range from source by
|
||||
/// detecting escaped tokens.
|
||||
/// Transforms source into a new [`VirtualSource`] using a `range`.
|
||||
///
|
||||
/// This function will extract the sub-source using the specified `range`, then escape `token` using the specified `escape` character.
|
||||
/// It will also keep a list of removed/added characters and build an offset list that will be passed to the newly created source, via [`VirtualSource::new_offsets`].
|
||||
///
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// If you only need to escape content that won't be parsed, use [`process_escaped`] instead.
|
||||
/// If you only need to escape content that won't be parsed, use [`escape_text`] instead.
|
||||
pub fn escape_source(
|
||||
source: Rc<dyn Source>,
|
||||
range: Range<usize>,
|
||||
|
@ -147,11 +150,11 @@ pub fn escape_source(
|
|||
}
|
||||
|
||||
/// Processed a string and escapes a single token out of it
|
||||
/// Escaped characters other than the [`token`] will be not be treated as escaped
|
||||
/// Escaped characters other than the [`Token`] will be not be treated as escaped
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// assert_eq!(process_escaped('\\', "%", "escaped: \\%, also escaped: \\\\\\%, untouched: \\a"),
|
||||
/// assert_eq!(scape_text('\\', "%", "escaped: \\%, also escaped: \\\\\\%, untouched: \\a"),
|
||||
/// "escaped: %, also escaped: \\%, untouched: \\a");
|
||||
/// ```
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue