pub struct Section { /* private fields */ }Expand description
One run of rows under a heading of its own.
Columns belong to a section rather than to the view, so two sections can differ: a section of what is overdue wants a column of how late, and a section of what is merely out does not. Sections that should line up are given the same columns.
Implementations§
Source§impl Section
impl Section
Sourcepub fn new(columns: impl IntoIterator<Item = Column>) -> Self
pub fn new(columns: impl IntoIterator<Item = Column>) -> Self
Examples found in repository?
examples/library/main.rs (line 634)
589 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
590 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
591 let branches = Self::branches(ctx)?;
592 let code = args.get_or("branch", "");
593 let branch = branches.iter().find(|b| b.code == code);
594 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
595
596 let genre = args.get_or("genre", "");
597 let subgenre = args.get_or("subgenre", "");
598 let author = args.get_or("author", "").trim().to_lowercase();
599
600 // The books this branch holds that answer the rest of the question,
601 // whether they are out or not. A parameter left empty asks nothing.
602 let held: Vec<&Book> = books
603 .iter()
604 .filter(|b| b.shelved.contains_key(code))
605 .filter(|b| genre.is_empty() || b.genre == genre)
606 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
607 .filter(|b| {
608 author.is_empty()
609 || format!("{} {}", b.author_first, b.author_last)
610 .to_lowercase()
611 .contains(&author)
612 })
613 .collect();
614
615 let now = today();
616 let mut out = Vec::new();
617 let mut overdue = Vec::new();
618 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
619 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
620 if days > 0 {
621 overdue.push(OnLoan::row(book, days));
622 } else {
623 out.push(OnLoan::row(book, days));
624 }
625 }
626
627 let lent = out.len() + overdue.len();
628 Ok(ViewData::new()
629 .note(format!(
630 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
631 held.len()
632 ))
633 .section(
634 Section::new(OnLoan::columns())
635 .heading("Out")
636 .note("Days left before they are due.")
637 .rows(out)?,
638 )
639 .section(
640 Section::new(OnLoan::columns())
641 .heading("Overdue")
642 .note("Days past due. Chase these.")
643 .rows(overdue)?,
644 ))
645 }Sourcepub fn heading(self, heading: impl Into<String>) -> Self
pub fn heading(self, heading: impl Into<String>) -> Self
Examples found in repository?
examples/library/main.rs (line 635)
589 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
590 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
591 let branches = Self::branches(ctx)?;
592 let code = args.get_or("branch", "");
593 let branch = branches.iter().find(|b| b.code == code);
594 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
595
596 let genre = args.get_or("genre", "");
597 let subgenre = args.get_or("subgenre", "");
598 let author = args.get_or("author", "").trim().to_lowercase();
599
600 // The books this branch holds that answer the rest of the question,
601 // whether they are out or not. A parameter left empty asks nothing.
602 let held: Vec<&Book> = books
603 .iter()
604 .filter(|b| b.shelved.contains_key(code))
605 .filter(|b| genre.is_empty() || b.genre == genre)
606 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
607 .filter(|b| {
608 author.is_empty()
609 || format!("{} {}", b.author_first, b.author_last)
610 .to_lowercase()
611 .contains(&author)
612 })
613 .collect();
614
615 let now = today();
616 let mut out = Vec::new();
617 let mut overdue = Vec::new();
618 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
619 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
620 if days > 0 {
621 overdue.push(OnLoan::row(book, days));
622 } else {
623 out.push(OnLoan::row(book, days));
624 }
625 }
626
627 let lent = out.len() + overdue.len();
628 Ok(ViewData::new()
629 .note(format!(
630 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
631 held.len()
632 ))
633 .section(
634 Section::new(OnLoan::columns())
635 .heading("Out")
636 .note("Days left before they are due.")
637 .rows(out)?,
638 )
639 .section(
640 Section::new(OnLoan::columns())
641 .heading("Overdue")
642 .note("Days past due. Chase these.")
643 .rows(overdue)?,
644 ))
645 }Sourcepub fn note(self, note: impl Into<String>) -> Self
pub fn note(self, note: impl Into<String>) -> Self
Examples found in repository?
examples/library/main.rs (line 636)
589 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
590 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
591 let branches = Self::branches(ctx)?;
592 let code = args.get_or("branch", "");
593 let branch = branches.iter().find(|b| b.code == code);
594 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
595
596 let genre = args.get_or("genre", "");
597 let subgenre = args.get_or("subgenre", "");
598 let author = args.get_or("author", "").trim().to_lowercase();
599
600 // The books this branch holds that answer the rest of the question,
601 // whether they are out or not. A parameter left empty asks nothing.
602 let held: Vec<&Book> = books
603 .iter()
604 .filter(|b| b.shelved.contains_key(code))
605 .filter(|b| genre.is_empty() || b.genre == genre)
606 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
607 .filter(|b| {
608 author.is_empty()
609 || format!("{} {}", b.author_first, b.author_last)
610 .to_lowercase()
611 .contains(&author)
612 })
613 .collect();
614
615 let now = today();
616 let mut out = Vec::new();
617 let mut overdue = Vec::new();
618 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
619 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
620 if days > 0 {
621 overdue.push(OnLoan::row(book, days));
622 } else {
623 out.push(OnLoan::row(book, days));
624 }
625 }
626
627 let lent = out.len() + overdue.len();
628 Ok(ViewData::new()
629 .note(format!(
630 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
631 held.len()
632 ))
633 .section(
634 Section::new(OnLoan::columns())
635 .heading("Out")
636 .note("Days left before they are due.")
637 .rows(out)?,
638 )
639 .section(
640 Section::new(OnLoan::columns())
641 .heading("Overdue")
642 .note("Days past due. Chase these.")
643 .rows(overdue)?,
644 ))
645 }Sourcepub fn rows<T: Serialize>(
self,
rows: impl IntoIterator<Item = T>,
) -> Result<Self, ApiError>
pub fn rows<T: Serialize>( self, rows: impl IntoIterator<Item = T>, ) -> Result<Self, ApiError>
The rows themselves, which may be a repository’s own types: whatever serializes to an object keyed by the fields the columns name.
A row that cannot be serialized is a 500 naming the section, since a page that quietly dropped a row would be worse than one that did not render.
Examples found in repository?
examples/library/main.rs (line 637)
589 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
590 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
591 let branches = Self::branches(ctx)?;
592 let code = args.get_or("branch", "");
593 let branch = branches.iter().find(|b| b.code == code);
594 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
595
596 let genre = args.get_or("genre", "");
597 let subgenre = args.get_or("subgenre", "");
598 let author = args.get_or("author", "").trim().to_lowercase();
599
600 // The books this branch holds that answer the rest of the question,
601 // whether they are out or not. A parameter left empty asks nothing.
602 let held: Vec<&Book> = books
603 .iter()
604 .filter(|b| b.shelved.contains_key(code))
605 .filter(|b| genre.is_empty() || b.genre == genre)
606 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
607 .filter(|b| {
608 author.is_empty()
609 || format!("{} {}", b.author_first, b.author_last)
610 .to_lowercase()
611 .contains(&author)
612 })
613 .collect();
614
615 let now = today();
616 let mut out = Vec::new();
617 let mut overdue = Vec::new();
618 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
619 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
620 if days > 0 {
621 overdue.push(OnLoan::row(book, days));
622 } else {
623 out.push(OnLoan::row(book, days));
624 }
625 }
626
627 let lent = out.len() + overdue.len();
628 Ok(ViewData::new()
629 .note(format!(
630 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
631 held.len()
632 ))
633 .section(
634 Section::new(OnLoan::columns())
635 .heading("Out")
636 .note("Days left before they are due.")
637 .rows(out)?,
638 )
639 .section(
640 Section::new(OnLoan::columns())
641 .heading("Overdue")
642 .note("Days past due. Chase these.")
643 .rows(overdue)?,
644 ))
645 }Trait Implementations§
Auto Trait Implementations§
impl Freeze for Section
impl RefUnwindSafe for Section
impl Send for Section
impl Sync for Section
impl Unpin for Section
impl UnsafeUnpin for Section
impl UnwindSafe for Section
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more