home ~ projects ~ socials

Use An Object As A Value In MiniJinja

This example is longer than it needs to be, but it's what I needed for Neopoligen.

```cargo
[dependencies]
minijinja = { version= "2.3.1" }
```

#![allow(dead_code)]
#![allow(unused_variables)]

use minijinja::value::Object;
use minijinja::value::Enumerator;
use minijinja::{Environment, context, Value};
use std::sync::Arc;
use std::collections::BTreeMap;

#[derive(Clone, Debug)]
pub struct Site {
  // pages: Arc<Vec<Page>>
  pages: <Value as Page>::from_dyn_object
}

impl Object for Site {
    fn enumerate(self: &Arc<Self>) -> Enumerator {
        Enumerator::Str(&["pages"])
    }
}

#[derive(Clone, Debug)]
pub struct Page {
  sections: Arc<Vec<Section>>
}

impl Object for Page {
    fn enumerate(self: &Arc<Self>) -> Enumerator {
        Enumerator::Str(&["sections"])
    }
}

#[derive(Clone, Debug)]
pub struct Section {
  attrs: Arc<BTreeMap<Arc<String>, Arc<Span>>> 
}

impl Object for Section {
    fn enumerate(self: &Arc<Self>) -> Enumerator {
        Enumerator::Str(&["attrs"])
    }
}

#[derive(Clone, Debug)]
pub struct Span {
  text: Arc<String>
}

impl Object for Span {
    fn enumerate(self: &Arc<Self>) -> Enumerator {
        Enumerator::Str(&["text"])
    }
}


fn main() {
  let mut attrs = BTreeMap::new();
  attrs.insert(
    Arc::new("alfa".to_string()), 
    Arc::new(
      Span { 
        text: Arc::new("bravo".to_string()) 
      }
    )
  );

  let site = Arc::new(Site{
    //pages: Value::from_dyn_object(Arc::<Vec<Page>>::new(vec![]))
    pages: Value::from_dyn_object(vec![])


/*
      pages: Arc::new(vec![
        Page {
          sections: Arc::new(vec![
            Section {
              attrs: Arc::new(attrs)
            }
          ])
        }
      ])
      */

    }
  );

  let mut env = Environment::new();
  env.add_template(
    "hello", "Hello! {{ site }}"
  ).unwrap();
  let skeleton = env.get_template("hello").unwrap();
  let output = skeleton.render(
    context!(
      site => Value::from_dyn_object(site)
    )
  ).unwrap();
  println!("{}", output);

}
Output:
error[E0223]: ambiguous associated type
  --> /Users/alan/.cargo/target/55/19854259915251/_active_nvim_run:18:10
   |
18 |   pages: Value::from_dyn_object<Page>
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
help: if there were a trait named `Example` with associated type `from_dyn_object` implemented for `Value`, you could use the fully-qualified path
   |
18 |   pages: <Value as Example>::from_dyn_object
   |          ~~~~~~~~~~~~~

error[E0277]: the trait bound `DynObject: From<Vec<_>>` is not satisfied
   --> /Users/alan/.cargo/target/55/19854259915251/_active_nvim_run:74:35
    |
74  |     pages: Value::from_dyn_object(vec![])
    |            ---------------------- ^^^^^^ the trait `From<Vec<_>>` is not implemented for `DynObject`, which is required by `Vec<_>: Into<DynObject>`
    |            |
    |            required by a bound introduced by this call
    |
    = help: the trait `From<Arc<_>>` is implemented for `DynObject`
    = help: for that trait implementation, expected `Arc<_>`, found `Vec<_>`
    = note: required for `Vec<_>` to implement `Into<DynObject>`
note: required by a bound in `Value::from_dyn_object`
   --> /Users/alan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/minijinja-2.3.1/src/value/mod.rs:814:31
    |
814 |     pub fn from_dyn_object<T: Into<DynObject>>(value: T) -> Value {
    |                               ^^^^^^^^^^^^^^^ required by this bound in `Value::from_dyn_object`

Some errors have detailed explanations: E0223, E0277.
For more information about an error, try `rustc --explain E0223`.
error: could not compile `_active_nvim_run` (bin "_active_nvim_run") due to 2 previous errors
-- end of line --

References