pub struct NodeTypeMap { /* private fields */ }Expand description
Represents the contents of the node-types.json in a form that can be converted to Rust code.
Implementations§
Source§impl NodeTypeMap
impl NodeTypeMap
pub fn get<Q: Ord + ?Sized>(&self, name: &Q) -> Option<&NodeType>
Sourcepub fn values(&self) -> impl Iterator<Item = &NodeType>
pub fn values(&self) -> impl Iterator<Item = &NodeType>
Get all NodeTypes
§Example
Checking that the grammar contains a node with a certain name:
let node_type_map = NodeTypeMap::try_from(tree_sitter_rust::NODE_TYPES)
.unwrap();
assert!(node_type_map.values()
.any(|node| node.name.sexp_name == "trait_item"));Sourcepub fn add_custom_supertype(
&mut self,
name: &str,
subtypes: impl IntoIterator<Item = NodeName>,
) -> Result<NodeName, NodeName>
pub fn add_custom_supertype( &mut self, name: &str, subtypes: impl IntoIterator<Item = NodeName>, ) -> Result<NodeName, NodeName>
Add a supertype that isn’t yet defined in the grammar.
This is meant for cases where the original grammar doesn’t include a supertype
that you would like to have in your use case AST. The most common case would
be to add an AllNodes supertype (see example below).
It’s also a good way to give an explicit name to a hidden node that is not a supertype in the original grammar.
§Examples
Adding supertypes for all named and unnamed nodes, and another one for all nodes:
let mut node_type_map = NodeTypeMap::try_from(tree_sitter_rust::NODE_TYPES).unwrap();
let (named, unnamed): (Vec<_>, Vec<_>) = node_type_map
.values()
.map(|node| node.name.clone())
.partition(|name| name.is_named);
let named = node_type_map
.add_custom_supertype("_all_named", named)
.expect("this shouldn't already exist");
let unnamed = node_type_map
.add_custom_supertype("_all_unnamed", unnamed)
.expect("this shouldn't already exist");
node_type_map
.add_custom_supertype("_all_nodes", vec![named, unnamed])
.expect("this shouldn't already exist");
let code = generate_nodes(node_type_map).unwrap().into_string();
assert!(code.contains("pub enum AllNamed"));
assert!(code.contains("pub enum AllUnnamed"));
assert!(code.contains("pub enum AllNodes"));Make the return type of StructDeclaration::body be StructBody instead of a generated
anonymous union type.
let mut node_type_map = NodeTypeMap::try_from(tree_sitter_rust::NODE_TYPES).unwrap();
let struct_body_variants = node_type_map["struct_item"]["body"].types.clone();
node_type_map.add_custom_supertype("_struct_body", struct_body_variants)
.expect("this shouldn't already exist");
let code = generate_nodes(node_type_map).unwrap().into_string();
assert!(code.contains("pub enum StructBody"));
assert!(code.contains("- `body`: `_struct_body?` ([`StructBody`])"));§Panics
Supertype names must be hidden (i.e. start with an underscore).
Therefore this function panics when name doesn’t have a leading _.
node_type_map.add_custom_supertype("my_supertype", vec![]); // Panic!§Return Value
Returns Ok(new_node_name) if the new supertype has been add ed,
or Err(existing_node_name) if a node with that name already exists:
let mut node_type_map = NodeTypeMap::try_from(tree_sitter_rust::NODE_TYPES).unwrap();
let declarations: Vec<NodeName> = node_type_map.values()
// select some declarations
.map(|node| node.name.clone())
.collect();
let result = node_type_map.add_custom_supertype("_declaration_statement", declarations.clone());
assert!(result.is_err()); // the Rust grammar already defines this name
let result = node_type_map.add_custom_supertype("_my_declaration_statement", declarations);
assert!(result.is_ok());