gazetta_core/view/
page.rs

1//  Copyright (C) 2015 Steven Allen
2//
3//  This file is part of gazetta.
4//
5//  This program is free software: you can redistribute it and/or modify it under the terms of the
6//  GNU General Public License as published by the Free Software Foundation version 3 of the
7//  License.
8//
9//  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
11//  the GNU General Public License for more details.
12//
13//  You should have received a copy of the GNU General Public License along with this program.  If
14//  not, see <http://www.gnu.org/licenses/>.
15//
16
17use std::fmt;
18use std::ops::Deref;
19
20use crate::model::DateTime;
21use crate::model::Entry;
22use crate::render::Gazetta;
23
24use super::Index;
25
26/// Represents the a page to be rendered, sans any links/references to other pages.
27pub struct BasePage<'a, G>
28where
29    G: Gazetta + 'a,
30    G::PageMeta: 'a,
31    G::SiteMeta: 'a,
32{
33    /// The page's title.
34    pub title: &'a str,
35
36    /// An optional description of the page.
37    pub description: Option<&'a str>,
38
39    /// The date the page was created (specified in the metadata).
40    pub date: Option<&'a DateTime>,
41
42    /// The date the page was last modified (derived from the file metadata and used for
43    /// syndication).
44    pub updated: &'a DateTime,
45
46    /// The page's location, relative to the site's base.
47    pub href: &'a str,
48
49    /// Extra metadata specified in the Entry.
50    pub meta: &'a G::PageMeta,
51
52    /// The page's content.
53    ///
54    /// If you want to use the default renderer, just render the page itself.
55    ///
56    /// ```norun
57    /// html! {
58    ///     div(id="content") : page;
59    /// }
60    /// ```
61    pub content: Content<'a>,
62}
63
64impl<'a, G> BasePage<'a, G>
65where
66    G: Gazetta + 'a,
67    G::PageMeta: 'a,
68    G::SiteMeta: 'a,
69{
70    /// Creates a base page for an entry.
71    pub fn for_entry(entry: &'a Entry<G::PageMeta>) -> Self {
72        BasePage {
73            title: &entry.title,
74            date: entry.date.as_ref(),
75            updated: &entry.updated,
76            description: entry.description.as_deref(),
77            content: Content {
78                data: &entry.content,
79                format: &entry.format,
80            },
81            href: &entry.name,
82            meta: &entry.meta,
83        }
84    }
85}
86
87impl<'a, G> Deref for BasePage<'a, G>
88where
89    G: Gazetta + 'a,
90    G::PageMeta: 'a,
91    G::SiteMeta: 'a,
92{
93    type Target = G::PageMeta;
94    fn deref(&self) -> &Self::Target {
95        self.meta
96    }
97}
98
99/// Represents an indevidual page to be rendered.
100pub struct Page<'a, G>
101where
102    G: Gazetta + 'a,
103    G::PageMeta: 'a,
104    G::SiteMeta: 'a,
105{
106    /// The base page containing all the content, etc.
107    pub base: BasePage<'a, G>,
108
109    /// The index that should be rendered in association with this page, if any.
110    pub index: Option<Index<'a, G>>,
111
112    /// The other pages referenced in this page's "cc" field (usually tags, categories, projects,
113    /// etc.).
114    pub references: &'a [BasePage<'a, G>],
115}
116
117impl<'a, G> Deref for Page<'a, G>
118where
119    G: Gazetta + 'a,
120    G::PageMeta: 'a,
121    G::SiteMeta: 'a,
122{
123    type Target = BasePage<'a, G>;
124
125    fn deref(&self) -> &Self::Target {
126        &self.base
127    }
128}
129
130#[derive(Copy, Clone, Debug)]
131pub struct Content<'a> {
132    pub data: &'a str,
133    pub format: &'a str,
134}
135
136// Implement these manually. Derive requires that G: Trait.
137
138impl<'a, G> Copy for BasePage<'a, G>
139where
140    G: Gazetta + 'a,
141    G::PageMeta: 'a,
142    G::SiteMeta: 'a,
143{
144}
145
146impl<'a, G> Clone for BasePage<'a, G>
147where
148    G: Gazetta + 'a,
149    G::PageMeta: 'a,
150    G::SiteMeta: 'a,
151{
152    fn clone(&self) -> Self {
153        *self
154    }
155}
156
157impl<'a, G> Copy for Page<'a, G>
158where
159    G: Gazetta + 'a,
160    G::PageMeta: 'a,
161    G::SiteMeta: 'a,
162{
163}
164
165impl<'a, G> Clone for Page<'a, G>
166where
167    G: Gazetta + 'a,
168    G::PageMeta: 'a,
169    G::SiteMeta: 'a,
170{
171    fn clone(&self) -> Self {
172        *self
173    }
174}
175
176impl<'a, G> fmt::Debug for Page<'a, G>
177where
178    G: Gazetta + 'a,
179    G::PageMeta: fmt::Debug + 'a,
180    G::SiteMeta: 'a,
181{
182    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
183        f.debug_struct("Page")
184            .field("title", &self.title)
185            .field("date", &self.date)
186            .field("href", &self.href)
187            .field("index", &self.index)
188            .field("meta", &self.meta)
189            .field("content", &self.content)
190            .finish()
191    }
192}