-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combining templates with fold
/match
-> no two closures have the same type.
#16
Comments
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 I wrote a 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. |
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 |
Closing as there's really nothing I can do about this. |
I want to fold some Horrorshow templates, I'm using Horrorshow to make directory listings. However, I'm having a hard time understanding how to make this work, because I can't
match
on the output ofhtml!
and I can'tfold
over them either.I'm sorry for the glorified support request, I'll try to rework your advice into a pull-request which adds examples to the documentation if you like.
Here's the code I want to write, but the only way to make it work I have found is passing around the rendered HTML by calling
.into_string().unwrap()
on thehtml!
output every time.(Sorry for the large blurb of code, the first
map
is largely irrelevant but I thought it would be useful for context.)The text was updated successfully, but these errors were encountered: