Giter VIP home page Giter VIP logo

Comments (3)

Stebalien avatar Stebalien commented on May 26, 2024

First off, I apologize for completely missing this issue; github occasionally drops email notifications and I rely on them completely 😞. In case you're still interested...

One solution is to use the html_box! macro, this will Box the resulting template so you should always get the same type out.

I wrote a template! macro for creating named templates for cases like this (where you want something with a fixed type) however, it currently borrows it's the captured variables so that won't help here either.

Personally, I recommend inverting this and not using map/fold:

fn list_directories_recursive(&self, path: &Path) -> Option<String> {
    let entries = path.read_dir().unwrap() 
        .filter_map(|de| de.ok())         // remove invalid paths
        .map(|de| de.path())              // DirectoryEntry -> Path
        .filter(|p| self.visible_path(p)) // remove invisible paths
        .map(|path| {
            let (href, name) = match (
                path.as_os_str().to_str(),
                path.file_name().and_then(|f|f.to_str())
            ) {
                (Some(href), Some(name)) => {
                    let href = href.replacen(".", "", 1); // ./thing -> /thing
                    let name = name.replacen("/", "", 1); // ./dir/thing -> thing
                    (href, name)
                }
                _ => return None,
            };
            return Some((path, href, name))
        })
        .filter_map(|s| s);

    let listings = (html! {
        @ for (path, href, name) in entries {
            @ if self.list_recursively && path.is_dir() {
                // No need to check if None. None renders as ""
                : self.list_directories_recursive(&path)
            }
            tr {
                td {
                    a(href=&href) : name
                }
            }
        }
    }).into_string().unwrap();

    if listings.len() != 0 {
        Some(listings)
    } else {
        None
    }
}

The other way to do this is an embedded closure:

fn list_directories_recursive(&self, path: &Path) -> Option<String> {
    let listings = (html! {
        |tmpl| path.read_dir().unwrap() 
            .filter_map(|de| de.ok())         // remove invalid paths
            .map(|de| de.path())              // DirectoryEntry -> Path
            .filter(|p| self.visible_path(p)) // remove invisible paths
            .map(|path| {
                let (href, name) = match (
                    path.as_os_str().to_str(),
                    path.file_name().and_then(|f|f.to_str())
                ) {
                    (Some(href), Some(name)) => {
                        let href = href.replacen(".", "", 1); // ./thing -> /thing
                        let name = name.replacen("/", "", 1); // ./dir/thing -> thing
                        (href, name)
                    }
                    _ => return None,
                };
                return Some((path, href, name))
            })
            .filter_map(|s| s)
            .for_each(|(path, href, name)| &mut *tmpl << html! {
                @ if self.list_recursively && path.is_dir() {
                    // No need to check if None. None renders as ""
                    : self.list_directories_recursive(&path)
                }
                tr {
                    td {
                        a(href=&href) : name
                    }
                }
            })
    }).into_string().unwrap();

    if listings.len() != 0 {
        Some(listings)
    } else {
        None
    }
}

but I prefer the first way.

from horrorshow-rs.

Stebalien avatar Stebalien commented on May 26, 2024

Actually, you could also use the following to avoid turning any intermediate templates into strings:

template! {
    // Where Context is the "Self" type.
    ListDirectories(ctx: &Context, path: &Path) {
        |tmpl| path.read_dir().unwrap() 
            .filter_map(|de| de.ok())         // remove invalid paths
            .map(|de| de.path())              // DirectoryEntry -> Path
            .filter(|p| ctx.visible_path(p))  // remove invisible paths
            .map(|path| {
                let (href, name) = match (
                    path.as_os_str().to_str(),
                    path.file_name().and_then(|f|f.to_str())
                ) {
                    (Some(href), Some(name)) => {
                        let href = href.replacen(".", "", 1); // ./thing -> /thing
                        let name = name.replacen("/", "", 1); // ./dir/thing -> thing
                        (href, name)
                    }
                    _ => return None,
                };
                return Some((path, href, name))
            })
            .filter_map(|s| s)
            .for_each(|(path, href, name)| &mut *tmpl << html! {
                @ if ctx.list_recursively && path.is_dir() {
                    : ListDirectories::new(ctx, &path)
                }
                tr {
                    td {
                        a(href=&href) : name
                    }
                }
            })
    }
}

You can use this by, e.g., calling ListDirectories::new(ctx, some_path).into_string().unwrap().

from horrorshow-rs.

Stebalien avatar Stebalien commented on May 26, 2024

Closing as there's really nothing I can do about this.

from horrorshow-rs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.