pub struct DetailSection { /* private fields */ }Expand description
One run of rows under a heading, in one of the page’s two columns.
Implementations§
Source§impl DetailSection
impl DetailSection
Sourcepub fn main(heading: impl Into<String>) -> Self
pub fn main(heading: impl Into<String>) -> Self
A section of the page’s main column, which is where what the reader came for goes.
Examples found in repository?
examples/library/main.rs (line 824)
809 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
810 let branches: Vec<Branch> = ctx.optional_rows(BRANCHES_FILE)?;
811 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
812 let code = args.get_or("branch", "");
813 let branch = branches
814 .iter()
815 .find(|b| b.code == code)
816 .ok_or_else(|| ApiError::new(404, format!("no branch has the code \"{code}\"")))?;
817
818 let (here, out) = shelf_counts(&books, code);
819 let now = today();
820
821 // What is out, with how it stands against its due date. A row's own
822 // link is the catalogue entry, and one book's link is a `javascript:`
823 // URL, which the page shows as text rather than following.
824 let mut lent = DetailSection::main("Out on loan");
825 for book in BranchDetail::by_rating(&books, code, true) {
826 let late = days_from_civil(&book.due).map(|due| now - due);
827 let mut row = DetailRow::new(book.title.as_str()).link(book.link.as_str());
828 if !book.due.is_empty() {
829 row = row.fact(format!("due {}", book.due));
830 }
831 row = match late {
832 Some(days) if days > 0 => row.fact(format!("{days} day(s) late")),
833 Some(days) => row.fact(format!("{} day(s) to go", -days)),
834 None => row.note("No due date is recorded."),
835 };
836 lent = lent.row(row.button(Button::disabled("Chase the borrower", "Not built yet")));
837 }
838 if out == 0 {
839 lent = lent.note("Everything this branch holds is on the shelf.");
840 }
841
842 // What can go out, ranked, with the one action this example offers.
843 let mut shelf = DetailSection::main("On the shelf")
844 .numbered()
845 .note("Best rated first.");
846 for book in BranchDetail::by_rating(&books, code, false) {
847 let mut row = DetailRow::new(book.title.as_str());
848 if let Some(rating) = book.rating {
849 row = row.fact(format!("rated {rating}"));
850 }
851 if let Some(year) = book.year {
852 row = row.fact(year);
853 }
854 if !book.notes.trim().is_empty() {
855 row = row.note(book.notes.as_str());
856 }
857 shelf = shelf.row(
858 row.button(Button::link("Catalogue", book.link.as_str()))
859 .button(Button::form(
860 "Lend it out",
861 BranchDetail::loan_form(&book.title),
862 )),
863 );
864 }
865 if here == out {
866 shelf = shelf.note("Nothing this branch holds is on the shelf today.");
867 }
868
869 let mut hours = DetailSection::side("When it is open").collapsed_on_phone();
870 for (day, open) in &branch.hours {
871 hours = hours.row(DetailRow::new(day.as_str()).fact(open.as_str()));
872 }
873 if branch.hours.is_empty() {
874 hours = hours.note("No hours are recorded for this branch.");
875 }
876
877 // A count per genre, which is a section of facts rather than of things
878 // to do, so it sits beside the page rather than in it.
879 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
880 for book in books.iter().filter(|b| b.shelved.contains_key(code)) {
881 *counts.entry(book.genre.as_str()).or_default() += 1;
882 }
883 let mut genres = DetailSection::side("Genres here");
884 for (genre, count) in counts {
885 genres = genres.row(DetailRow::new(genre).fact(count));
886 }
887
888 Ok(ViewData::new().detail(
889 Detail::new(branch.name.as_str())
890 .status(if branch.open.unwrap_or(false) {
891 Status::new("Open", Tone::Good)
892 } else {
893 Status::new("Shut", Tone::Neutral)
894 })
895 .subtitle(format!(
896 "{}, {} staff, {here} book(s) here, {out} out",
897 librarian(branch),
898 branch.staff.unwrap_or(0)
899 ))
900 .back(ViewLink::new("all-branches"))
901 .section(lent)
902 .section(shelf)
903 .section(hours)
904 .section(genres),
905 ))
906 }Sourcepub fn side(heading: impl Into<String>) -> Self
pub fn side(heading: impl Into<String>) -> Self
A section of the page’s side column, which is where what is worth knowing but not acting on goes. On a phone there is one column, and the sections keep the order they were given in.
Examples found in repository?
examples/library/main.rs (line 869)
809 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
810 let branches: Vec<Branch> = ctx.optional_rows(BRANCHES_FILE)?;
811 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
812 let code = args.get_or("branch", "");
813 let branch = branches
814 .iter()
815 .find(|b| b.code == code)
816 .ok_or_else(|| ApiError::new(404, format!("no branch has the code \"{code}\"")))?;
817
818 let (here, out) = shelf_counts(&books, code);
819 let now = today();
820
821 // What is out, with how it stands against its due date. A row's own
822 // link is the catalogue entry, and one book's link is a `javascript:`
823 // URL, which the page shows as text rather than following.
824 let mut lent = DetailSection::main("Out on loan");
825 for book in BranchDetail::by_rating(&books, code, true) {
826 let late = days_from_civil(&book.due).map(|due| now - due);
827 let mut row = DetailRow::new(book.title.as_str()).link(book.link.as_str());
828 if !book.due.is_empty() {
829 row = row.fact(format!("due {}", book.due));
830 }
831 row = match late {
832 Some(days) if days > 0 => row.fact(format!("{days} day(s) late")),
833 Some(days) => row.fact(format!("{} day(s) to go", -days)),
834 None => row.note("No due date is recorded."),
835 };
836 lent = lent.row(row.button(Button::disabled("Chase the borrower", "Not built yet")));
837 }
838 if out == 0 {
839 lent = lent.note("Everything this branch holds is on the shelf.");
840 }
841
842 // What can go out, ranked, with the one action this example offers.
843 let mut shelf = DetailSection::main("On the shelf")
844 .numbered()
845 .note("Best rated first.");
846 for book in BranchDetail::by_rating(&books, code, false) {
847 let mut row = DetailRow::new(book.title.as_str());
848 if let Some(rating) = book.rating {
849 row = row.fact(format!("rated {rating}"));
850 }
851 if let Some(year) = book.year {
852 row = row.fact(year);
853 }
854 if !book.notes.trim().is_empty() {
855 row = row.note(book.notes.as_str());
856 }
857 shelf = shelf.row(
858 row.button(Button::link("Catalogue", book.link.as_str()))
859 .button(Button::form(
860 "Lend it out",
861 BranchDetail::loan_form(&book.title),
862 )),
863 );
864 }
865 if here == out {
866 shelf = shelf.note("Nothing this branch holds is on the shelf today.");
867 }
868
869 let mut hours = DetailSection::side("When it is open").collapsed_on_phone();
870 for (day, open) in &branch.hours {
871 hours = hours.row(DetailRow::new(day.as_str()).fact(open.as_str()));
872 }
873 if branch.hours.is_empty() {
874 hours = hours.note("No hours are recorded for this branch.");
875 }
876
877 // A count per genre, which is a section of facts rather than of things
878 // to do, so it sits beside the page rather than in it.
879 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
880 for book in books.iter().filter(|b| b.shelved.contains_key(code)) {
881 *counts.entry(book.genre.as_str()).or_default() += 1;
882 }
883 let mut genres = DetailSection::side("Genres here");
884 for (genre, count) in counts {
885 genres = genres.row(DetailRow::new(genre).fact(count));
886 }
887
888 Ok(ViewData::new().detail(
889 Detail::new(branch.name.as_str())
890 .status(if branch.open.unwrap_or(false) {
891 Status::new("Open", Tone::Good)
892 } else {
893 Status::new("Shut", Tone::Neutral)
894 })
895 .subtitle(format!(
896 "{}, {} staff, {here} book(s) here, {out} out",
897 librarian(branch),
898 branch.staff.unwrap_or(0)
899 ))
900 .back(ViewLink::new("all-branches"))
901 .section(lent)
902 .section(shelf)
903 .section(hours)
904 .section(genres),
905 ))
906 }Sourcepub fn note(self, note: impl Into<String>) -> Self
pub fn note(self, note: impl Into<String>) -> Self
A sentence under the heading, which is also what a section with no rows says instead of them.
Examples found in repository?
examples/library/main.rs (line 839)
809 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
810 let branches: Vec<Branch> = ctx.optional_rows(BRANCHES_FILE)?;
811 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
812 let code = args.get_or("branch", "");
813 let branch = branches
814 .iter()
815 .find(|b| b.code == code)
816 .ok_or_else(|| ApiError::new(404, format!("no branch has the code \"{code}\"")))?;
817
818 let (here, out) = shelf_counts(&books, code);
819 let now = today();
820
821 // What is out, with how it stands against its due date. A row's own
822 // link is the catalogue entry, and one book's link is a `javascript:`
823 // URL, which the page shows as text rather than following.
824 let mut lent = DetailSection::main("Out on loan");
825 for book in BranchDetail::by_rating(&books, code, true) {
826 let late = days_from_civil(&book.due).map(|due| now - due);
827 let mut row = DetailRow::new(book.title.as_str()).link(book.link.as_str());
828 if !book.due.is_empty() {
829 row = row.fact(format!("due {}", book.due));
830 }
831 row = match late {
832 Some(days) if days > 0 => row.fact(format!("{days} day(s) late")),
833 Some(days) => row.fact(format!("{} day(s) to go", -days)),
834 None => row.note("No due date is recorded."),
835 };
836 lent = lent.row(row.button(Button::disabled("Chase the borrower", "Not built yet")));
837 }
838 if out == 0 {
839 lent = lent.note("Everything this branch holds is on the shelf.");
840 }
841
842 // What can go out, ranked, with the one action this example offers.
843 let mut shelf = DetailSection::main("On the shelf")
844 .numbered()
845 .note("Best rated first.");
846 for book in BranchDetail::by_rating(&books, code, false) {
847 let mut row = DetailRow::new(book.title.as_str());
848 if let Some(rating) = book.rating {
849 row = row.fact(format!("rated {rating}"));
850 }
851 if let Some(year) = book.year {
852 row = row.fact(year);
853 }
854 if !book.notes.trim().is_empty() {
855 row = row.note(book.notes.as_str());
856 }
857 shelf = shelf.row(
858 row.button(Button::link("Catalogue", book.link.as_str()))
859 .button(Button::form(
860 "Lend it out",
861 BranchDetail::loan_form(&book.title),
862 )),
863 );
864 }
865 if here == out {
866 shelf = shelf.note("Nothing this branch holds is on the shelf today.");
867 }
868
869 let mut hours = DetailSection::side("When it is open").collapsed_on_phone();
870 for (day, open) in &branch.hours {
871 hours = hours.row(DetailRow::new(day.as_str()).fact(open.as_str()));
872 }
873 if branch.hours.is_empty() {
874 hours = hours.note("No hours are recorded for this branch.");
875 }
876
877 // A count per genre, which is a section of facts rather than of things
878 // to do, so it sits beside the page rather than in it.
879 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
880 for book in books.iter().filter(|b| b.shelved.contains_key(code)) {
881 *counts.entry(book.genre.as_str()).or_default() += 1;
882 }
883 let mut genres = DetailSection::side("Genres here");
884 for (genre, count) in counts {
885 genres = genres.row(DetailRow::new(genre).fact(count));
886 }
887
888 Ok(ViewData::new().detail(
889 Detail::new(branch.name.as_str())
890 .status(if branch.open.unwrap_or(false) {
891 Status::new("Open", Tone::Good)
892 } else {
893 Status::new("Shut", Tone::Neutral)
894 })
895 .subtitle(format!(
896 "{}, {} staff, {here} book(s) here, {out} out",
897 librarian(branch),
898 branch.staff.unwrap_or(0)
899 ))
900 .back(ViewLink::new("all-branches"))
901 .section(lent)
902 .section(shelf)
903 .section(hours)
904 .section(genres),
905 ))
906 }Sourcepub fn numbered(self) -> Self
pub fn numbered(self) -> Self
Number the rows, for a section whose order is a ranking: the first row is the one to do something about.
Examples found in repository?
examples/library/main.rs (line 844)
809 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
810 let branches: Vec<Branch> = ctx.optional_rows(BRANCHES_FILE)?;
811 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
812 let code = args.get_or("branch", "");
813 let branch = branches
814 .iter()
815 .find(|b| b.code == code)
816 .ok_or_else(|| ApiError::new(404, format!("no branch has the code \"{code}\"")))?;
817
818 let (here, out) = shelf_counts(&books, code);
819 let now = today();
820
821 // What is out, with how it stands against its due date. A row's own
822 // link is the catalogue entry, and one book's link is a `javascript:`
823 // URL, which the page shows as text rather than following.
824 let mut lent = DetailSection::main("Out on loan");
825 for book in BranchDetail::by_rating(&books, code, true) {
826 let late = days_from_civil(&book.due).map(|due| now - due);
827 let mut row = DetailRow::new(book.title.as_str()).link(book.link.as_str());
828 if !book.due.is_empty() {
829 row = row.fact(format!("due {}", book.due));
830 }
831 row = match late {
832 Some(days) if days > 0 => row.fact(format!("{days} day(s) late")),
833 Some(days) => row.fact(format!("{} day(s) to go", -days)),
834 None => row.note("No due date is recorded."),
835 };
836 lent = lent.row(row.button(Button::disabled("Chase the borrower", "Not built yet")));
837 }
838 if out == 0 {
839 lent = lent.note("Everything this branch holds is on the shelf.");
840 }
841
842 // What can go out, ranked, with the one action this example offers.
843 let mut shelf = DetailSection::main("On the shelf")
844 .numbered()
845 .note("Best rated first.");
846 for book in BranchDetail::by_rating(&books, code, false) {
847 let mut row = DetailRow::new(book.title.as_str());
848 if let Some(rating) = book.rating {
849 row = row.fact(format!("rated {rating}"));
850 }
851 if let Some(year) = book.year {
852 row = row.fact(year);
853 }
854 if !book.notes.trim().is_empty() {
855 row = row.note(book.notes.as_str());
856 }
857 shelf = shelf.row(
858 row.button(Button::link("Catalogue", book.link.as_str()))
859 .button(Button::form(
860 "Lend it out",
861 BranchDetail::loan_form(&book.title),
862 )),
863 );
864 }
865 if here == out {
866 shelf = shelf.note("Nothing this branch holds is on the shelf today.");
867 }
868
869 let mut hours = DetailSection::side("When it is open").collapsed_on_phone();
870 for (day, open) in &branch.hours {
871 hours = hours.row(DetailRow::new(day.as_str()).fact(open.as_str()));
872 }
873 if branch.hours.is_empty() {
874 hours = hours.note("No hours are recorded for this branch.");
875 }
876
877 // A count per genre, which is a section of facts rather than of things
878 // to do, so it sits beside the page rather than in it.
879 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
880 for book in books.iter().filter(|b| b.shelved.contains_key(code)) {
881 *counts.entry(book.genre.as_str()).or_default() += 1;
882 }
883 let mut genres = DetailSection::side("Genres here");
884 for (genre, count) in counts {
885 genres = genres.row(DetailRow::new(genre).fact(count));
886 }
887
888 Ok(ViewData::new().detail(
889 Detail::new(branch.name.as_str())
890 .status(if branch.open.unwrap_or(false) {
891 Status::new("Open", Tone::Good)
892 } else {
893 Status::new("Shut", Tone::Neutral)
894 })
895 .subtitle(format!(
896 "{}, {} staff, {here} book(s) here, {out} out",
897 librarian(branch),
898 branch.staff.unwrap_or(0)
899 ))
900 .back(ViewLink::new("all-branches"))
901 .section(lent)
902 .section(shelf)
903 .section(hours)
904 .section(genres),
905 ))
906 }Sourcepub fn collapsed_on_phone(self) -> Self
pub fn collapsed_on_phone(self) -> Self
Start the section shut on a phone, where a page of everything at once is a page of scrolling. It is open wherever there is room for it beside the main column.
Examples found in repository?
examples/library/main.rs (line 869)
809 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
810 let branches: Vec<Branch> = ctx.optional_rows(BRANCHES_FILE)?;
811 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
812 let code = args.get_or("branch", "");
813 let branch = branches
814 .iter()
815 .find(|b| b.code == code)
816 .ok_or_else(|| ApiError::new(404, format!("no branch has the code \"{code}\"")))?;
817
818 let (here, out) = shelf_counts(&books, code);
819 let now = today();
820
821 // What is out, with how it stands against its due date. A row's own
822 // link is the catalogue entry, and one book's link is a `javascript:`
823 // URL, which the page shows as text rather than following.
824 let mut lent = DetailSection::main("Out on loan");
825 for book in BranchDetail::by_rating(&books, code, true) {
826 let late = days_from_civil(&book.due).map(|due| now - due);
827 let mut row = DetailRow::new(book.title.as_str()).link(book.link.as_str());
828 if !book.due.is_empty() {
829 row = row.fact(format!("due {}", book.due));
830 }
831 row = match late {
832 Some(days) if days > 0 => row.fact(format!("{days} day(s) late")),
833 Some(days) => row.fact(format!("{} day(s) to go", -days)),
834 None => row.note("No due date is recorded."),
835 };
836 lent = lent.row(row.button(Button::disabled("Chase the borrower", "Not built yet")));
837 }
838 if out == 0 {
839 lent = lent.note("Everything this branch holds is on the shelf.");
840 }
841
842 // What can go out, ranked, with the one action this example offers.
843 let mut shelf = DetailSection::main("On the shelf")
844 .numbered()
845 .note("Best rated first.");
846 for book in BranchDetail::by_rating(&books, code, false) {
847 let mut row = DetailRow::new(book.title.as_str());
848 if let Some(rating) = book.rating {
849 row = row.fact(format!("rated {rating}"));
850 }
851 if let Some(year) = book.year {
852 row = row.fact(year);
853 }
854 if !book.notes.trim().is_empty() {
855 row = row.note(book.notes.as_str());
856 }
857 shelf = shelf.row(
858 row.button(Button::link("Catalogue", book.link.as_str()))
859 .button(Button::form(
860 "Lend it out",
861 BranchDetail::loan_form(&book.title),
862 )),
863 );
864 }
865 if here == out {
866 shelf = shelf.note("Nothing this branch holds is on the shelf today.");
867 }
868
869 let mut hours = DetailSection::side("When it is open").collapsed_on_phone();
870 for (day, open) in &branch.hours {
871 hours = hours.row(DetailRow::new(day.as_str()).fact(open.as_str()));
872 }
873 if branch.hours.is_empty() {
874 hours = hours.note("No hours are recorded for this branch.");
875 }
876
877 // A count per genre, which is a section of facts rather than of things
878 // to do, so it sits beside the page rather than in it.
879 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
880 for book in books.iter().filter(|b| b.shelved.contains_key(code)) {
881 *counts.entry(book.genre.as_str()).or_default() += 1;
882 }
883 let mut genres = DetailSection::side("Genres here");
884 for (genre, count) in counts {
885 genres = genres.row(DetailRow::new(genre).fact(count));
886 }
887
888 Ok(ViewData::new().detail(
889 Detail::new(branch.name.as_str())
890 .status(if branch.open.unwrap_or(false) {
891 Status::new("Open", Tone::Good)
892 } else {
893 Status::new("Shut", Tone::Neutral)
894 })
895 .subtitle(format!(
896 "{}, {} staff, {here} book(s) here, {out} out",
897 librarian(branch),
898 branch.staff.unwrap_or(0)
899 ))
900 .back(ViewLink::new("all-branches"))
901 .section(lent)
902 .section(shelf)
903 .section(hours)
904 .section(genres),
905 ))
906 }Sourcepub fn row(self, row: DetailRow) -> Self
pub fn row(self, row: DetailRow) -> Self
Examples found in repository?
examples/library/main.rs (line 836)
809 fn render(&self, args: &ViewArgs, ctx: &Context) -> Result<ViewData, ApiError> {
810 let branches: Vec<Branch> = ctx.optional_rows(BRANCHES_FILE)?;
811 let books: Vec<Book> = ctx.optional_rows(BOOKS_FILE)?;
812 let code = args.get_or("branch", "");
813 let branch = branches
814 .iter()
815 .find(|b| b.code == code)
816 .ok_or_else(|| ApiError::new(404, format!("no branch has the code \"{code}\"")))?;
817
818 let (here, out) = shelf_counts(&books, code);
819 let now = today();
820
821 // What is out, with how it stands against its due date. A row's own
822 // link is the catalogue entry, and one book's link is a `javascript:`
823 // URL, which the page shows as text rather than following.
824 let mut lent = DetailSection::main("Out on loan");
825 for book in BranchDetail::by_rating(&books, code, true) {
826 let late = days_from_civil(&book.due).map(|due| now - due);
827 let mut row = DetailRow::new(book.title.as_str()).link(book.link.as_str());
828 if !book.due.is_empty() {
829 row = row.fact(format!("due {}", book.due));
830 }
831 row = match late {
832 Some(days) if days > 0 => row.fact(format!("{days} day(s) late")),
833 Some(days) => row.fact(format!("{} day(s) to go", -days)),
834 None => row.note("No due date is recorded."),
835 };
836 lent = lent.row(row.button(Button::disabled("Chase the borrower", "Not built yet")));
837 }
838 if out == 0 {
839 lent = lent.note("Everything this branch holds is on the shelf.");
840 }
841
842 // What can go out, ranked, with the one action this example offers.
843 let mut shelf = DetailSection::main("On the shelf")
844 .numbered()
845 .note("Best rated first.");
846 for book in BranchDetail::by_rating(&books, code, false) {
847 let mut row = DetailRow::new(book.title.as_str());
848 if let Some(rating) = book.rating {
849 row = row.fact(format!("rated {rating}"));
850 }
851 if let Some(year) = book.year {
852 row = row.fact(year);
853 }
854 if !book.notes.trim().is_empty() {
855 row = row.note(book.notes.as_str());
856 }
857 shelf = shelf.row(
858 row.button(Button::link("Catalogue", book.link.as_str()))
859 .button(Button::form(
860 "Lend it out",
861 BranchDetail::loan_form(&book.title),
862 )),
863 );
864 }
865 if here == out {
866 shelf = shelf.note("Nothing this branch holds is on the shelf today.");
867 }
868
869 let mut hours = DetailSection::side("When it is open").collapsed_on_phone();
870 for (day, open) in &branch.hours {
871 hours = hours.row(DetailRow::new(day.as_str()).fact(open.as_str()));
872 }
873 if branch.hours.is_empty() {
874 hours = hours.note("No hours are recorded for this branch.");
875 }
876
877 // A count per genre, which is a section of facts rather than of things
878 // to do, so it sits beside the page rather than in it.
879 let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
880 for book in books.iter().filter(|b| b.shelved.contains_key(code)) {
881 *counts.entry(book.genre.as_str()).or_default() += 1;
882 }
883 let mut genres = DetailSection::side("Genres here");
884 for (genre, count) in counts {
885 genres = genres.row(DetailRow::new(genre).fact(count));
886 }
887
888 Ok(ViewData::new().detail(
889 Detail::new(branch.name.as_str())
890 .status(if branch.open.unwrap_or(false) {
891 Status::new("Open", Tone::Good)
892 } else {
893 Status::new("Shut", Tone::Neutral)
894 })
895 .subtitle(format!(
896 "{}, {} staff, {here} book(s) here, {out} out",
897 librarian(branch),
898 branch.staff.unwrap_or(0)
899 ))
900 .back(ViewLink::new("all-branches"))
901 .section(lent)
902 .section(shelf)
903 .section(hours)
904 .section(genres),
905 ))
906 }pub fn rows(self, rows: impl IntoIterator<Item = DetailRow>) -> Self
Trait Implementations§
Source§impl Clone for DetailSection
impl Clone for DetailSection
Source§impl Debug for DetailSection
impl Debug for DetailSection
Auto Trait Implementations§
impl Freeze for DetailSection
impl RefUnwindSafe for DetailSection
impl Send for DetailSection
impl Sync for DetailSection
impl Unpin for DetailSection
impl UnsafeUnpin for DetailSection
impl UnwindSafe for DetailSection
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