mirror of
				https://github.com/askama-rs/askama.git
				synced 2025-11-04 07:23:15 +00:00 
			
		
		
		
	Implement Render even if parsing failed
				
					
				
			This makes error messages much more readable.
This commit is contained in:
		
							parent
							
								
									a95fca43ac
								
							
						
					
					
						commit
						c48532fb17
					
				@ -36,7 +36,7 @@ impl Heritage<'_> {
 | 
			
		||||
 | 
			
		||||
type BlockAncestry<'a> = HashMap<&'a str, Vec<(&'a Context<'a>, &'a BlockDef<'a>)>>;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
#[derive(Default, Clone)]
 | 
			
		||||
pub(crate) struct Context<'a> {
 | 
			
		||||
    pub(crate) nodes: &'a [Node<'a>],
 | 
			
		||||
    pub(crate) extends: Option<Rc<Path>>,
 | 
			
		||||
 | 
			
		||||
@ -332,6 +332,14 @@ impl TemplateArgs {
 | 
			
		||||
        Ok(args)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn fallback() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            source: Some(Source::Source("".to_string())),
 | 
			
		||||
            ext: Some("txt".to_string()),
 | 
			
		||||
            ..Self::default()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn config(&self) -> Result<String, CompileError> {
 | 
			
		||||
        read_config_file(self.config.as_deref())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -23,8 +23,24 @@ pub fn derive_template(input: TokenStream) -> TokenStream {
 | 
			
		||||
    let ast = syn::parse::<syn::DeriveInput>(input).unwrap();
 | 
			
		||||
    match build_template(&ast) {
 | 
			
		||||
        Ok(source) => source.parse().unwrap(),
 | 
			
		||||
        Err(e) => e.into_compile_error(),
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            let mut e = e.into_compile_error();
 | 
			
		||||
            if let Ok(source) = build_skeleton(&ast) {
 | 
			
		||||
                let source: TokenStream = source.parse().unwrap();
 | 
			
		||||
                e.extend(source);
 | 
			
		||||
            }
 | 
			
		||||
            e
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn build_skeleton(ast: &syn::DeriveInput) -> Result<String, CompileError> {
 | 
			
		||||
    let template_args = TemplateArgs::fallback();
 | 
			
		||||
    let config = Config::new("", None)?;
 | 
			
		||||
    let input = TemplateInput::new(ast, &config, &template_args)?;
 | 
			
		||||
    let mut contexts = HashMap::new();
 | 
			
		||||
    contexts.insert(&input.path, Context::default());
 | 
			
		||||
    Generator::new(&input, &contexts, None, MapChain::default()).build(&contexts[&input.path])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Takes a `syn::DeriveInput` and generates source code for it
 | 
			
		||||
 | 
			
		||||
@ -6,16 +6,3 @@ error: failed to parse template source at row 1, column 27 near:
 | 
			
		||||
  |          ^^^^^^^^
 | 
			
		||||
  |
 | 
			
		||||
  = note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
 | 
			
		||||
 | 
			
		||||
error[E0599]: no method named `render` found for struct `A` in the current scope
 | 
			
		||||
  --> tests/ui/filter_block_ws.rs:11:7
 | 
			
		||||
   |
 | 
			
		||||
8  | struct A;
 | 
			
		||||
   | -------- method `render` not found for this struct
 | 
			
		||||
...
 | 
			
		||||
11 |     A.render().unwrap();
 | 
			
		||||
   |       ^^^^^^ method not found in `A`
 | 
			
		||||
   |
 | 
			
		||||
   = help: items from traits can only be used if the trait is implemented and in scope
 | 
			
		||||
   = note: the following trait defines an item `render`, perhaps you need to implement it:
 | 
			
		||||
           candidate #1: `Template`
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user