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 618)
573 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
574 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
575 let branches = Self::branches(ctx)?;
576 let code = args.get_or("branch", "");
577 let branch = branches.iter().find(|b| b.code == code);
578 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
579
580 let genre = args.get_or("genre", "");
581 let subgenre = args.get_or("subgenre", "");
582 let author = args.get_or("author", "").trim().to_lowercase();
583
584 // The books this branch holds that answer the rest of the question,
585 // whether they are out or not. A parameter left empty asks nothing.
586 let held: Vec<&Book> = books
587 .iter()
588 .filter(|b| b.shelved.contains_key(code))
589 .filter(|b| genre.is_empty() || b.genre == genre)
590 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
591 .filter(|b| {
592 author.is_empty()
593 || format!("{} {}", b.author_first, b.author_last)
594 .to_lowercase()
595 .contains(&author)
596 })
597 .collect();
598
599 let now = today();
600 let mut out = Vec::new();
601 let mut overdue = Vec::new();
602 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
603 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
604 if days > 0 {
605 overdue.push(OnLoan::row(book, days));
606 } else {
607 out.push(OnLoan::row(book, days));
608 }
609 }
610
611 let lent = out.len() + overdue.len();
612 Ok(ViewData::new()
613 .note(format!(
614 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
615 held.len()
616 ))
617 .section(
618 Section::new(OnLoan::columns())
619 .heading("Out")
620 .note("Days left before they are due.")
621 .rows(out)?,
622 )
623 .section(
624 Section::new(OnLoan::columns())
625 .heading("Overdue")
626 .note("Days past due. Chase these.")
627 .rows(overdue)?,
628 ))
629 }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 619)
573 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
574 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
575 let branches = Self::branches(ctx)?;
576 let code = args.get_or("branch", "");
577 let branch = branches.iter().find(|b| b.code == code);
578 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
579
580 let genre = args.get_or("genre", "");
581 let subgenre = args.get_or("subgenre", "");
582 let author = args.get_or("author", "").trim().to_lowercase();
583
584 // The books this branch holds that answer the rest of the question,
585 // whether they are out or not. A parameter left empty asks nothing.
586 let held: Vec<&Book> = books
587 .iter()
588 .filter(|b| b.shelved.contains_key(code))
589 .filter(|b| genre.is_empty() || b.genre == genre)
590 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
591 .filter(|b| {
592 author.is_empty()
593 || format!("{} {}", b.author_first, b.author_last)
594 .to_lowercase()
595 .contains(&author)
596 })
597 .collect();
598
599 let now = today();
600 let mut out = Vec::new();
601 let mut overdue = Vec::new();
602 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
603 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
604 if days > 0 {
605 overdue.push(OnLoan::row(book, days));
606 } else {
607 out.push(OnLoan::row(book, days));
608 }
609 }
610
611 let lent = out.len() + overdue.len();
612 Ok(ViewData::new()
613 .note(format!(
614 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
615 held.len()
616 ))
617 .section(
618 Section::new(OnLoan::columns())
619 .heading("Out")
620 .note("Days left before they are due.")
621 .rows(out)?,
622 )
623 .section(
624 Section::new(OnLoan::columns())
625 .heading("Overdue")
626 .note("Days past due. Chase these.")
627 .rows(overdue)?,
628 ))
629 }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 620)
573 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
574 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
575 let branches = Self::branches(ctx)?;
576 let code = args.get_or("branch", "");
577 let branch = branches.iter().find(|b| b.code == code);
578 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
579
580 let genre = args.get_or("genre", "");
581 let subgenre = args.get_or("subgenre", "");
582 let author = args.get_or("author", "").trim().to_lowercase();
583
584 // The books this branch holds that answer the rest of the question,
585 // whether they are out or not. A parameter left empty asks nothing.
586 let held: Vec<&Book> = books
587 .iter()
588 .filter(|b| b.shelved.contains_key(code))
589 .filter(|b| genre.is_empty() || b.genre == genre)
590 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
591 .filter(|b| {
592 author.is_empty()
593 || format!("{} {}", b.author_first, b.author_last)
594 .to_lowercase()
595 .contains(&author)
596 })
597 .collect();
598
599 let now = today();
600 let mut out = Vec::new();
601 let mut overdue = Vec::new();
602 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
603 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
604 if days > 0 {
605 overdue.push(OnLoan::row(book, days));
606 } else {
607 out.push(OnLoan::row(book, days));
608 }
609 }
610
611 let lent = out.len() + overdue.len();
612 Ok(ViewData::new()
613 .note(format!(
614 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
615 held.len()
616 ))
617 .section(
618 Section::new(OnLoan::columns())
619 .heading("Out")
620 .note("Days left before they are due.")
621 .rows(out)?,
622 )
623 .section(
624 Section::new(OnLoan::columns())
625 .heading("Overdue")
626 .note("Days past due. Chase these.")
627 .rows(overdue)?,
628 ))
629 }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 621)
573 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
574 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
575 let branches = Self::branches(ctx)?;
576 let code = args.get_or("branch", "");
577 let branch = branches.iter().find(|b| b.code == code);
578 let named = branch.map(|b| b.name.as_str()).unwrap_or(code);
579
580 let genre = args.get_or("genre", "");
581 let subgenre = args.get_or("subgenre", "");
582 let author = args.get_or("author", "").trim().to_lowercase();
583
584 // The books this branch holds that answer the rest of the question,
585 // whether they are out or not. A parameter left empty asks nothing.
586 let held: Vec<&Book> = books
587 .iter()
588 .filter(|b| b.shelved.contains_key(code))
589 .filter(|b| genre.is_empty() || b.genre == genre)
590 .filter(|b| subgenre.is_empty() || b.subgenre == subgenre)
591 .filter(|b| {
592 author.is_empty()
593 || format!("{} {}", b.author_first, b.author_last)
594 .to_lowercase()
595 .contains(&author)
596 })
597 .collect();
598
599 let now = today();
600 let mut out = Vec::new();
601 let mut overdue = Vec::new();
602 for book in held.iter().filter(|b| b.lent.unwrap_or(false)) {
603 let days = days_from_civil(&book.due).map(|due| now - due).unwrap_or(0);
604 if days > 0 {
605 overdue.push(OnLoan::row(book, days));
606 } else {
607 out.push(OnLoan::row(book, days));
608 }
609 }
610
611 let lent = out.len() + overdue.len();
612 Ok(ViewData::new()
613 .note(format!(
614 "{lent} of {} book(s) at {named} are out on loan. A title links to its catalogue entry.",
615 held.len()
616 ))
617 .section(
618 Section::new(OnLoan::columns())
619 .heading("Out")
620 .note("Days left before they are due.")
621 .rows(out)?,
622 )
623 .section(
624 Section::new(OnLoan::columns())
625 .heading("Overdue")
626 .note("Days past due. Chase these.")
627 .rows(overdue)?,
628 ))
629 }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