@@ -3,6 +3,8 @@ use std::path::{Path, PathBuf};
33use std:: ptr:: NonNull ;
44
55use libloading:: { Library , Symbol } ;
6+ #[ cfg( feature = "tree-sitter-language" ) ]
7+ use tree_sitter_language:: LanguageFn ;
68
79/// Lowest supported ABI version of a grammar.
810// WARNING: update when updating vendored c sources
@@ -44,18 +46,21 @@ impl Grammar {
4446 } ) ?
4547 } ;
4648 let language_fn_name = format ! ( "tree_sitter_{}" , name. replace( '-' , "_" ) ) ;
47- let grammar = unsafe {
48- let language_fn: Symbol < unsafe extern "C" fn ( ) -> NonNull < GrammarData > > = library
49- . get ( language_fn_name. as_bytes ( ) )
50- . map_err ( |err| Error :: DlSym {
51- err,
52- symbol : name. to_owned ( ) ,
53- } ) ?;
54- Grammar { ptr : language_fn ( ) }
55- } ;
49+ let language_fn: Symbol < unsafe extern "C" fn ( ) -> NonNull < GrammarData > > = library
50+ . get ( language_fn_name. as_bytes ( ) )
51+ . map_err ( |err| Error :: DlSym {
52+ err,
53+ symbol : name. to_owned ( ) ,
54+ } ) ?;
55+ let grammar = Grammar :: from_grammar_data ( language_fn ( ) ) ?;
56+ std:: mem:: forget ( library) ;
57+ Ok ( grammar)
58+ }
59+
60+ fn from_grammar_data ( ptr : NonNull < GrammarData > ) -> Result < Grammar , Error > {
61+ let grammar = Grammar { ptr } ;
5662 let version = grammar. abi_version ( ) ;
5763 if ( MIN_COMPATIBLE_ABI_VERSION ..=ABI_VERSION ) . contains ( & version) {
58- std:: mem:: forget ( library) ;
5964 Ok ( grammar)
6065 } else {
6166 Err ( Error :: IncompatibleVersion { version } )
@@ -72,6 +77,16 @@ impl Grammar {
7277 }
7378}
7479
80+ #[ cfg( feature = "tree-sitter-language" ) ]
81+ impl TryFrom < LanguageFn > for Grammar {
82+ type Error = Error ;
83+
84+ fn try_from ( builder : LanguageFn ) -> Result < Self , Self :: Error > {
85+ let ptr = unsafe { NonNull :: new_unchecked ( builder. into_raw ( ) ( ) . cast_mut ( ) . cast ( ) ) } ;
86+ Self :: from_grammar_data ( ptr)
87+ }
88+ }
89+
7590#[ derive( thiserror:: Error , Debug ) ]
7691pub enum Error {
7792 #[ error( "Error opening dynamic library {path:?}" ) ]
0 commit comments