1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ Copyright: (c) 2023, Mike 'PhiSyX' S. (https://github.com/PhiSyX)         ┃
// ┃ SPDX-License-Identifier: MPL-2.0                                          ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃                                                                           ┃
// ┃  This Source Code Form is subject to the terms of the Mozilla Public      ┃
// ┃  License, v. 2.0. If a copy of the MPL was not distributed with this      ┃
// ┃  file, You can obtain one at https://mozilla.org/MPL/2.0/.                ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

// --------- //
// Interface //
// --------- //

pub trait ViewInterface {
	type Metadata: Default;
	type Scripts: Default;
	type Styles: Default;
	type View;

	/// Mise en page de la vue.
	type Layout: ViewLayoutInterface<
		Metadata = Self::Metadata,
		Scripts = Self::Scripts,
		Styles = Self::Styles,
		View = Self::View,
	>;

	/// Les méta-données de la vue.
	///
	/// NOTE: Dans la mise en page par défaut, les méta-données sont appliquées
	/// à l'intérieur de la balise `<head> ici </head>`. Elles correspondent
	/// généralement aux balises `<meta>`.
	fn metadata(&self) -> Self::Metadata {
		Default::default()
	}

	/// Les scripts de la vue.
	///
	/// NOTE: Dans la mise en page par défaut, les scripts sont appliqués avant
	/// la fermeture l'intérieur de la balise `</body>`.
	fn scripts(&self) -> Self::Scripts {
		Default::default()
	}

	/// Les styles de la vue.
	///
	/// NOTE: Dans la mise en page par défaut, les styles sont appliqués à
	/// l'intérieur de la balise `<head> ici </head>`, après les méta-données.
	fn styles(&self) -> Self::Styles {
		Default::default()
	}

	/// Le titre de la vue.
	fn title(&self) -> String;

	/// L'HTML de la vue.
	fn view(&self) -> Self::View;

	/// Le rendu de la mise en page + de la vue.
	fn render(&self) -> Self::View {
		let mut layout = <Self::Layout>::new();

		layout.set_title(self.title());
		layout.set_body(self.view());

		layout.add_meta(self.metadata());
		layout.add_script(self.scripts());
		layout.add_style(self.styles());

		layout.view()
	}
}

pub trait ViewLayoutInterface {
	type Metadata: Default;
	type Scripts: Default;
	type Styles: Default;
	type View;

	/// Crée une nouvelle instance de la [mise en page](Self).
	fn new() -> Self
	where
		Self: Sized;

	/// Applique un titre au document de la mise en page.
	fn set_title(&mut self, title: impl ToString);
	/// Applique un corps à la mise en page.
	fn set_body(&mut self, body: Self::View);

	/// Ajoute une méta-données au document de la mise en page.
	fn add_meta(&mut self, meta: Self::Metadata);
	/// Ajoute un script au document de la mise en page.
	fn add_script(&mut self, script: Self::Scripts);
	/// Ajoute un style au document de la mise en page.
	fn add_style(&mut self, style: Self::Styles);

	/// L'HTML du document de la mise en page.
	fn view(&self) -> Self::View;
}