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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
use crate::video::{Platform, Restriction, Uploader, Video};
use crate::video_error::VideoError;
use chrono::{DateTime, FixedOffset};
/// A sitemap video.
///
/// This is a Builder for Video.
///
/// It's required to provide either a <video:content_loc> or <video:player_loc> tag.
/// We recommend that your provide the <video:content_loc> tag, if possible.
/// This is the most effective way for Google to fetch your video content files.
/// If <video:content_loc> isn't available, provide <video:player_loc> as an alternative.
#[derive(Debug, Clone)]
pub struct VideoBuilder {
/// A URL pointing to the video thumbnail image file.
pub thumbnail_location: String,
/// The title of the video.
///
/// All HTML entities must be escaped or wrapped in a CDATA block.
/// We recommend that this match the video title displayed on the web page.
pub title: String,
/// A description of the video.
///
/// Maximum 2048 characters.
/// All HTML entities must be escaped or wrapped in a CDATA block.
/// It must match the description displayed on the web page (it doesn't need to be a word-for-word match).
pub description: String,
/// A URL pointing to the actual video media file.
///
/// The file must be one of the supported formats.
/// - HTML and Flash aren't supported formats.
/// - Must not be the same as the <loc> URL.
/// - This is the equivalent of VideoObject.contentUrl in structured data.
/// - Best practice: If you want to restrict access to your content but still have it crawled, ensure that Googlebot can access your content by using a reverse DNS lookup.
pub content_location: String,
/// A URL pointing to a player for a specific video.
///
/// Usually this is the information in the src element of an <embed> tag.
/// - Must not be the same as the <loc> URL.
/// - For `YouTube` videos, this value is used rather than `video:content_loc`. This is the equivalent of VideoObject.embedUrl in structured data.
/// - Best practice: If you want to restrict access to your content but still have it crawled, ensure that Googlebot can access your content by using a reverse DNS lookup.
pub player_location: String,
/// The duration of the video, in seconds.
///
/// Value must be from 1 to 28800 (8 hours) inclusive.
pub duration: Option<u16>,
/// The date after which the video is no longer be available, in W3C format.
///
/// Omit this tag if your video does not expire.
/// If present, Google Search won't show your video after this date.
/// For recurring videos at the same URL, update the expiration date to the new expiration date.
pub expiration_date: Option<DateTime<FixedOffset>>,
/// The rating of the video.
///
/// Supported values are float numbers in the range 0.0 (low) to 5.0 (high), inclusive.
pub rating: Option<f32>,
/// The number of times the video has been viewed.
pub view_count: Option<usize>,
/// The date the video was first published, in W3C format.
pub publication_date: Option<DateTime<FixedOffset>>,
/// Whether the video is available with `SafeSearch`.
///
/// If you omit this tag, the video is available when `SafeSearch` is turned on.
pub family_friendly: Option<bool>,
/// Whether to show or hide your video in search results from specific countries.
///
/// Specify a space-delimited list of country codes in ISO 3166 format.
/// Only one <video:restriction> tag can be used for each video.
/// If there is no <video:restriction> tag, Google assumes that the video can be shown in all locations.
/// Note that this tag only affects search results; it doesn't prevent a user from finding or playing your video in a restricted location though other means.
pub restriction: Option<Restriction>,
/// Whether to show or hide your video in search results on specified platform types.
///
/// This is a list of space-delimited platform types.
/// Note that this only affects search results on the specified device types; it does not prevent a user from playing your video on a restricted platform.
/// Only one <video:platform> tag can appear for each video.
/// If there is no <video:platform> tag, Google assumes that the video can be played on all platforms.
pub platform: Option<Platform>,
/// Indicates whether a subscription is required to view the video.
pub requires_subscription: Option<bool>,
/// The video uploader's name.
///
/// Only one <video:uploader> is allowed per video.
/// The string value can be a maximum of 255 characters.
pub uploader: Option<Uploader>,
/// Indicates whether the video is a live stream.
pub live: Option<bool>,
/// An arbitrary string tag describing the video.
///
/// Tags are generally very short descriptions of key concepts associated with a video or piece of content.
/// A single video could have several tags, although it might belong to only one category.
/// For example, a video about grilling food may belong in the "grilling" category, but could be tagged "steak", "meat", "summer", and "outdoor".
/// Create a new <video:tag> element for each tag associated with a video.
/// A maximum of 32 tags is permitted.
pub tags: Option<Vec<String>>,
}
impl VideoBuilder {
#[must_use]
pub const fn new(
thumbnail_location: String,
title: String,
description: String,
content_location: String,
player_location: String,
) -> Self {
Self {
thumbnail_location,
title,
description,
content_location,
player_location,
duration: None,
expiration_date: None,
rating: None,
view_count: None,
publication_date: None,
family_friendly: None,
restriction: None,
platform: None,
requires_subscription: None,
uploader: None,
live: None,
tags: None,
}
}
pub fn duration(&mut self, duration: u16) -> &mut Self {
self.duration = Some(duration);
self
}
pub fn expiration_date(&mut self, expiration_date: DateTime<FixedOffset>) -> &mut Self {
self.expiration_date = Some(expiration_date);
self
}
pub fn rating(&mut self, rating: f32) -> &mut Self {
self.rating = Some(rating);
self
}
pub fn view_count(&mut self, view_count: usize) -> &mut Self {
self.view_count = Some(view_count);
self
}
pub fn publication_date(&mut self, publication_date: DateTime<FixedOffset>) -> &mut Self {
self.publication_date = Some(publication_date);
self
}
pub fn family_friendly(&mut self, family_friendly: bool) -> &mut Self {
self.family_friendly = Some(family_friendly);
self
}
pub fn restriction(&mut self, restriction: Restriction) -> &mut Self {
self.restriction = Some(restriction);
self
}
pub fn platform(&mut self, platform: Platform) -> &mut Self {
self.platform = Some(platform);
self
}
pub fn requires_subscription(&mut self, requires_subscription: bool) -> &mut Self {
self.requires_subscription = Some(requires_subscription);
self
}
pub fn uploader(&mut self, uploader: Uploader) -> &mut Self {
self.uploader = Some(uploader);
self
}
pub fn live(&mut self, live: bool) -> &mut Self {
self.live = Some(live);
self
}
pub fn tags(&mut self, tags: Vec<String>) -> &mut Self {
self.tags = Some(tags);
self
}
/// # Errors
///
/// Will return `VideoError::DescriptionTooLong` if `description` is longer than `2048` characters .
/// Will return `VideoError::DurationTooShort` if `duration` is below `1` second.
/// Will return `VideoError::DurationTooLong` if `duration` is above `28,800` seconds (`8` hours).
/// Will return `VideoError::RatingTooLow` if `rating` is below `0.0`.
/// Will return `VideoError::RatingTooHigh` if `rating` is above `5.0`.
/// Will return `VideoError::UploaderNameTooLong` if `uploader` `name` is longer than `255` characters.
/// Will return `VideoError::TooManyTags` if there are more than `32` `tags`.
pub fn build(&self) -> Result<Video, VideoError> {
Video::new(
self.thumbnail_location.clone(),
self.title.clone(),
self.description.clone(),
self.content_location.clone(),
self.player_location.clone(),
self.duration,
self.expiration_date,
self.rating,
self.view_count,
self.publication_date,
self.family_friendly,
self.restriction.clone(),
self.platform.clone(),
self.requires_subscription,
self.uploader.clone(),
self.live,
self.tags.clone(),
)
}
}