2

我正在研究一个proc_macro2/syn宏,并且我一直在使用Cursor对某些东西进行低级解析...... Rust- like。但是在我的语法深处,我需要解析一个syn::Type. 据我所知,唯一真正好的方法是使用impl syn::parse::Parsefor syn::Type

所以我真正想找到的是一种编写签名函数的好方法

fn parse_generic<T: Parse>(c: Cursor) -> Option<(T, Cursor)>;

那么我的问题是实现这种类型的功能的最佳(最简单,问题最少)方法是什么?


这是迄今为止我想出的最好的:

fn parse_generic<T: Parse>(mut c: Cursor) -> Option<(T, Cursor)> {                                                                       
    match T::parse.parse2(c.token_stream()) {                                                                                            
        Ok(t) => Some((t, Cursor::empty())), // because parse2 checks for end-of-stream!                                                 
        Err(e) => {                                                                                                                      
            // OK, because parse2 checks for end-of-stream, let's chop                                                                   
            // the input at the position of the error and try again (!).                                                                 
            let mut collected = Vec::new();                                                                                              
            let upto = e.span().start();                                                                                                 
            while !c.eof() && c.span().start() != upto {                                                                                 
                let (tt, next) = c.token_tree().unwrap();                                                                                
                collected.push(tt);                                                                                                      
                c = next;                                                                                                                
            }                                                                                                                            
            match T::parse.parse2(collected.into_iter().collect()) {                                                                     
                Ok(t) => Some((t, c)),                                                                                                   
                Err(_) => None,                                                                                                          
            }                                                                                                                            
        }                                                                                                                                
    }                                                                                                                                    
}                                                                                                                                        

这不是灾难性的,但也不理想。

4

0 回答 0