tree_sitter_graph/
lib.rs

1// -*- coding: utf-8 -*-
2// ------------------------------------------------------------------------------------------------
3// Copyright © 2021, tree-sitter authors.
4// Licensed under either of Apache License, Version 2.0, or MIT license, at your option.
5// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
6// ------------------------------------------------------------------------------------------------
7
8//! This library defines a [DSL][] for constructing arbitrary graph structures from source code
9//! that has been parsed using [tree-sitter][].
10//!
11//! [DSL]: reference/index.html
12//! [tree-sitter]: https://docs.rs/tree-sitter/
13//! [tree-sitter-python]: https://docs.rs/tree-sitter-python/
14//!
15//! # Overview
16//!
17//! You can use [tree-sitter][] to parse the content of source code into a _concrete syntax tree_.
18//! There are many interesting use cases where you want to use this parsed syntax tree to create
19//! some _other_ graph structure.  This library lets you do that, using a declarative [DSL][] to
20//! identify patterns in the parsed syntax tree, along with rules for which nodes and edges to
21//! create for the syntax nodes that match those patterns.  You can also annotate each node and
22//! edge with an arbitrary set of attributes.
23//!
24//! There are no limitations on what graph structure you create: you are not limited to creating a
25//! tree, and in particular, you are not limited to creating a tree that "lines" up with the parsed
26//! syntax tree.
27
28#[cfg(doc)]
29pub mod reference;
30
31pub mod ast;
32mod checker;
33mod execution;
34pub mod functions;
35pub mod graph;
36pub mod parse_error;
37mod parser;
38mod variables;
39
40pub use execution::error::ExecutionError;
41pub use execution::CancellationError;
42pub use execution::CancellationFlag;
43pub use execution::ExecutionConfig;
44pub use execution::Match;
45pub use execution::NoCancellation;
46pub use parser::Location;
47pub use parser::ParseError;
48pub use variables::Globals as Variables;
49pub use variables::Iter as VariableIter;
50pub use variables::VariableError;
51
52use std::borrow::Borrow;
53use std::hash::Hash;
54use std::ops::Deref;
55use std::sync::Arc;
56
57use serde::Serialize;
58use serde::Serializer;
59
60/// An identifier that appears in a graph DSL file or in the graph that is produced as an output.
61#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
62pub struct Identifier(Arc<String>);
63
64impl Identifier {
65    pub fn as_str(&self) -> &str {
66        self.0.as_str()
67    }
68
69    pub fn into_string(mut self) -> String {
70        Arc::make_mut(&mut self.0);
71        Arc::try_unwrap(self.0).unwrap()
72    }
73}
74
75impl Borrow<str> for Identifier {
76    fn borrow(&self) -> &str {
77        self.as_str()
78    }
79}
80
81impl Deref for Identifier {
82    type Target = str;
83    fn deref(&self) -> &str {
84        self.as_str()
85    }
86}
87
88impl std::fmt::Display for Identifier {
89    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
90        self.0.fmt(f)
91    }
92}
93
94impl From<&str> for Identifier {
95    fn from(value: &str) -> Identifier {
96        Identifier(Arc::new(String::from(value)))
97    }
98}
99
100impl Hash for Identifier {
101    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
102        self.0.hash(state);
103    }
104}
105
106impl PartialEq<str> for Identifier {
107    fn eq(&self, other: &str) -> bool {
108        self.as_str() == other
109    }
110}
111
112impl<'a> PartialEq<&'a str> for Identifier {
113    fn eq(&self, other: &&'a str) -> bool {
114        self.as_str() == *other
115    }
116}
117
118impl Serialize for Identifier {
119    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
120        serializer.serialize_str(self.as_str())
121    }
122}