winget_types/manifests/locale/mod.rs
1mod agreement;
2mod author;
3mod copyright;
4mod description;
5mod documentation;
6mod icon;
7mod installation_notes;
8mod license;
9mod moniker;
10mod package_name;
11mod publisher;
12mod release_notes;
13mod short_description;
14mod tag;
15
16use alloc::collections::BTreeSet;
17
18pub use agreement::Agreement;
19pub use author::{Author, AuthorError};
20pub use copyright::{Copyright, CopyrightError};
21pub use description::{Description, DescriptionError};
22pub use documentation::{DocumentLabel, Documentation};
23pub use icon::Icon;
24pub use installation_notes::{InstallationNotes, InstallationNotesError};
25pub use license::{License, LicenseError};
26pub use moniker::Moniker;
27pub use package_name::{PackageName, PackageNameError};
28pub use publisher::{Publisher, PublisherError};
29pub use release_notes::{ReleaseNotes, ReleaseNotesError};
30pub use short_description::{ShortDescription, ShortDescriptionError};
31pub use tag::{Tag, TagError};
32use url::Url;
33
34use crate::{
35 LanguageTag, Manifest, ManifestType, ManifestVersion, PackageIdentifier, PackageVersion,
36 url::{
37 CopyrightUrl, LicenseUrl, PackageUrl, PublisherSupportUrl, PublisherUrl, ReleaseNotesUrl,
38 },
39};
40
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[cfg_attr(feature = "serde", serde(rename_all = "PascalCase"))]
43pub struct DefaultLocaleManifest {
44 /// The unique identifier for a given package.
45 ///
46 /// This value is generally in the form of `Publisher.Package`. It is case-sensitive, and this
47 /// value must match the folder structure under the partition directory in GitHub.
48 pub package_identifier: PackageIdentifier,
49
50 /// The version of the package.
51 ///
52 /// It is related to the specific release this manifests targets. In some cases you will see a
53 /// perfectly formed [semantic version] number, and in other cases you might see something
54 /// different. These may be date driven, or they might have other characters with some package
55 /// specific meaning for example.
56 ///
57 /// The Windows Package Manager client uses this version to determine if an upgrade for a
58 /// package is available. In some cases, packages may be released with a marketing driven
59 /// version, and that causes trouble with the [`winget upgrade`] command.
60 ///
61 /// The current best practice is to use the value reported in Add / Remove Programs when this
62 /// version of the package is installed. In some cases, packages do not report a version
63 /// resulting in an upgrade loop or other unwanted behavior.
64 ///
65 /// [semantic version]: https://semver.org/
66 /// [`winget upgrade`]: https://docs.microsoft.com/windows/package-manager/winget/upgrade
67 pub package_version: PackageVersion,
68
69 /// The locale for package metadata.
70 ///
71 /// The format is BCP-47. This value identifies the language for meta-data to be displayed to a
72 /// user when no locale file matching their preferences is available. The Microsoft community
73 /// package repository validation pipelines also use this value to determine appropriate
74 /// validation rules for this file.
75 pub package_locale: LanguageTag,
76
77 /// The name of the publisher for a given package.
78 ///
79 /// This field is intended to allow the full publisher's or ISV's name to be displayed as they
80 /// wish.
81 ///
82 /// With the 1.9 release of the Windows Package Manager, this name affects how packages from a
83 /// source are mapped to Apps installed in Windows 10 and Windows 11 via Add / Remove Programs
84 /// (ARP) and Windows Apps & Features respectively. The best practice is to ensure this matches
85 /// the entry for the package when it has been installed. This should be the value of the
86 /// `Publisher` sub-key for the package in the [Windows registry]. The impact is associated with
87 /// `winget upgrade` and `winget list`.
88 ///
89 /// [Windows registry]: https://learn.microsoft.com/windows/win32/msi/uninstall-registry-key
90 pub publisher: Publisher,
91
92 /// The website for the publisher or ISV.
93 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
94 pub publisher_url: Option<PublisherUrl>,
95
96 /// The website for the publisher or ISV.
97 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
98 pub publisher_support_url: Option<PublisherSupportUrl>,
99
100 /// The privacy website or specific web page provided the publisher or ISV.
101 ///
102 /// If there is a privacy website or specific web page for the package it is preferred over a
103 /// generic privacy page for the publisher.
104 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
105 pub privacy_url: Option<Url>,
106
107 /// The author of a package.
108 ///
109 /// In some cases, the author is an individual who develops and or maintains the package. In
110 /// other cases this may be a URL pointing to the contributors web page for a package.
111 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
112 pub author: Option<Author>,
113
114 /// The name of the package.
115 ///
116 /// This field is intended to allow the full package name to be displayed as the publisher or
117 /// ISV wishes.
118 ///
119 /// With the 1.9 release of the Windows Package Manager, this name affects how packages from a
120 /// source are mapped to Apps installed in Windows 10 via Add / Remove Programs (ARP). The best
121 /// practice is to ensure this matches the ARP entry for the package name when it has been
122 /// installed. This should be the value of the `DisplayName` subkey for the package in the
123 /// [Windows registry]. The impact is associated with `winget upgrade` and `winget list`.
124 ///
125 /// [Windows registry]: https://learn.microsoft.com/windows/win32/msi/uninstall-registry-key
126 pub package_name: PackageName,
127
128 /// The website for the package.
129 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
130 pub package_url: Option<PackageUrl>,
131
132 /// The license governing the use and or distribution for the product.
133 ///
134 /// This could be an open source license, or a commercial license. Please note that a copyright
135 /// is not considered a license. If there is no available information on a product's license,
136 /// [`Proprietary`] should be the value in this field.
137 ///
138 /// [`Proprietary`]: License::PROPRIETARY
139 pub license: License,
140
141 /// The license website or specific web page provided the publisher or ISV.
142 ///
143 /// If there is a license website or specific web page for the package it is preferred over a
144 /// generic license page for the publisher.
145 ///
146 /// If this is a link to the license file for an open source project, it should be specific to
147 /// the version for the package. Some open source projects change their license over time.
148 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
149 pub license_url: Option<LicenseUrl>,
150
151 /// The copyright for the package.
152 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
153 pub copyright: Option<Copyright>,
154
155 /// The copyright website or specific web page provided the publisher or ISV.
156 ///
157 /// If there is a copyright website or specific web page for the package it is preferred over a
158 /// generic copyright page for the publisher.
159 ///
160 /// If this is a link to the copyright file for an open source project, it should be specific to
161 /// the version for the package. Some open source projects change their copyright over time.
162 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
163 pub copyright_url: Option<CopyrightUrl>,
164
165 /// The description for a package.
166 ///
167 /// It is intended for use in `winget show` to help a user understand what the package is.
168 ///
169 /// This should be something descriptive about what the package does, and it should not simply
170 /// state something like `<package name> installer` or `<package name> setup`.
171 pub short_description: ShortDescription,
172
173 /// The full or long description for a package.
174 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
175 pub description: Option<Description>,
176
177 /// The most common term users would search for when installing or upgrading a package.
178 ///
179 /// If only one package uses this moniker, then the [install], [list] and [upgrade] command may
180 /// match with this package.
181 ///
182 /// Moniker is the third property evaluated when searching for a matching package.
183 ///
184 /// [install]: https://docs.microsoft.com/windows/package-manager/winget/install
185 /// [list]: https://docs.microsoft.com/windows/package-manager/winget/list
186 /// [upgrade]: https://docs.microsoft.com/windows/package-manager/winget/upgrade
187 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
188 pub moniker: Option<Moniker>,
189
190 /// Other common term users would search for when looking for packages.
191 ///
192 /// Tags should be pertinent to what a user might search for when looking for a specific
193 /// package.
194 ///
195 /// The best practice is to present these terms in all lower case with hyphens rather than
196 /// spaces.
197 #[cfg_attr(
198 feature = "serde",
199 serde(skip_serializing_if = "BTreeSet::is_empty", default)
200 )]
201 pub tags: BTreeSet<Tag>,
202
203 /// Any agreements a user must accept prior to download and subsequent install or upgrade.
204 ///
205 /// Agreements are only allowed in the community repository when the manifest is maintained by a
206 /// verified developer.
207 #[cfg_attr(
208 feature = "serde",
209 serde(skip_serializing_if = "BTreeSet::is_empty", default)
210 )]
211 pub agreements: BTreeSet<Agreement>,
212
213 /// The release notes for a package.
214 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
215 pub release_notes: Option<ReleaseNotes>,
216
217 /// Release notes webpage for a package.
218 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
219 pub release_notes_url: Option<ReleaseNotesUrl>,
220
221 /// The purchase url for acquiring entitlement for a package.
222 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
223 pub purchase_url: Option<Url>,
224
225 /// The notes displayed to the user upon completion of a package installation.
226 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
227 pub installation_notes: Option<InstallationNotes>,
228
229 /// Any documentation for providing software guides such as manuals and troubleshooting URLs.
230 #[cfg_attr(
231 feature = "serde",
232 serde(skip_serializing_if = "BTreeSet::is_empty", default)
233 )]
234 pub documentations: BTreeSet<Documentation>,
235
236 #[cfg_attr(
237 feature = "serde",
238 serde(skip_serializing_if = "BTreeSet::is_empty", default)
239 )]
240 pub icons: BTreeSet<Icon>,
241
242 /// The manifest type.
243 ///
244 /// Must have the value [`defaultLocale`]. The Microsoft community package repository validation
245 /// pipelines also use this value to determine appropriate validation rules when evaluating this
246 /// file.
247 ///
248 /// [`defaultLocale`]: ManifestType::DefaultLocale
249 #[cfg_attr(feature = "serde", serde(default = "ManifestType::default_locale"))]
250 pub manifest_type: ManifestType,
251
252 /// The manifest syntax version.
253 ///
254 /// Must have the value `1.12.0`. The Microsoft community package repository validation
255 /// pipelines also use this value to determine appropriate validation rules when evaluating this
256 /// file.
257 #[cfg_attr(feature = "serde", serde(default))]
258 pub manifest_version: ManifestVersion,
259}
260
261impl Default for DefaultLocaleManifest {
262 fn default() -> Self {
263 Self {
264 package_identifier: PackageIdentifier::default(),
265 package_version: PackageVersion::default(),
266 package_locale: LanguageTag::default(),
267 publisher: Publisher::default(),
268 publisher_url: None,
269 publisher_support_url: None,
270 privacy_url: None,
271 author: None,
272 package_name: PackageName::default(),
273 package_url: None,
274 license: License::default(),
275 license_url: None,
276 copyright: None,
277 copyright_url: None,
278 short_description: ShortDescription::default(),
279 description: None,
280 moniker: None,
281 tags: BTreeSet::default(),
282 agreements: BTreeSet::default(),
283 release_notes: None,
284 release_notes_url: None,
285 purchase_url: None,
286 installation_notes: None,
287 documentations: BTreeSet::default(),
288 icons: BTreeSet::default(),
289 manifest_type: ManifestType::DefaultLocale,
290 manifest_version: ManifestVersion::default(),
291 }
292 }
293}
294
295impl Manifest for DefaultLocaleManifest {
296 const SCHEMA: &'static str = "https://aka.ms/winget-manifest.defaultLocale.1.12.0.schema.json";
297
298 const TYPE: ManifestType = ManifestType::DefaultLocale;
299
300 fn package_identifier(&self) -> &PackageIdentifier {
301 &self.package_identifier
302 }
303
304 fn package_version(&self) -> &PackageVersion {
305 &self.package_version
306 }
307
308 fn manifest_version(&self) -> ManifestVersion {
309 self.manifest_version
310 }
311
312 fn update_manifest_version(&mut self) {
313 self.manifest_version.update();
314 }
315}
316
317#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
318#[cfg_attr(feature = "serde", serde(rename_all = "PascalCase"))]
319pub struct LocaleManifest {
320 /// The unique identifier for a given package.
321 ///
322 /// This value is generally in the form of `Publisher.Package`. It is case-sensitive, and this
323 /// value must match the folder structure under the partition directory in GitHub.
324 pub package_identifier: PackageIdentifier,
325
326 /// The version of the package.
327 ///
328 /// It is related to the specific release this manifests targets. In some cases you will see a
329 /// perfectly formed [semantic version] number, and in other cases you might see something
330 /// different. These may be date driven, or they might have other characters with some package
331 /// specific meaning for example.
332 ///
333 /// The Windows Package Manager client uses this version to determine if an upgrade for a
334 /// package is available. In some cases, packages may be released with a marketing driven
335 /// version, and that causes trouble with the [`winget upgrade`] command.
336 ///
337 /// The current best practice is to use the value reported in Add / Remove Programs when this
338 /// version of the package is installed. In some cases, packages do not report a version
339 /// resulting in an upgrade loop or other unwanted behavior.
340 ///
341 /// [semantic version]: https://semver.org/
342 /// [`winget upgrade`]: https://docs.microsoft.com/windows/package-manager/winget/upgrade
343 pub package_version: PackageVersion,
344
345 /// The locale for package metadata.
346 ///
347 /// The format is BCP-47. This value identifies the language for meta-data to be displayed to a
348 /// user when no locale file matching their preferences is available. The Microsoft community
349 /// package repository validation pipelines also use this value to determine appropriate
350 /// validation rules for this file.
351 pub package_locale: LanguageTag,
352
353 /// The name of the publisher for a given package.
354 ///
355 /// This field is intended to allow the full publisher's or ISV's name to be displayed as they
356 /// wish.
357 ///
358 /// With the 1.9 release of the Windows Package Manager, this name affects how packages from a
359 /// source are mapped to Apps installed in Windows 10 and Windows 11 via Add / Remove Programs
360 /// (ARP) and Windows Apps & Features respectively. The best practice is to ensure this matches
361 /// the entry for the package when it has been installed. This should be the value of the
362 /// `Publisher` sub-key for the package in the [Windows registry]. The impact is associated with
363 /// `winget upgrade` and `winget list`.
364 ///
365 /// [Windows registry]: https://learn.microsoft.com/windows/win32/msi/uninstall-registry-key
366 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
367 pub publisher: Option<Publisher>,
368
369 /// The website for the publisher or ISV.
370 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
371 pub publisher_url: Option<PublisherUrl>,
372
373 /// The website for the publisher or ISV.
374 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
375 pub publisher_support_url: Option<PublisherSupportUrl>,
376
377 /// The privacy website or specific web page provided the publisher or ISV.
378 ///
379 /// If there is a privacy website or specific web page for the package it is preferred over a
380 /// generic privacy page for the publisher.
381 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
382 pub privacy_url: Option<Url>,
383
384 /// The author of a package.
385 ///
386 /// In some cases, the author is an individual who develops and or maintains the package. In
387 /// other cases this may be a URL pointing to the contributors web page for a package.
388 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
389 pub author: Option<Author>,
390
391 /// The name of the package.
392 ///
393 /// This field is intended to allow the full package name to be displayed as the publisher or
394 /// ISV wishes.
395 ///
396 /// With the 1.9 release of the Windows Package Manager, this name affects how packages from a
397 /// source are mapped to Apps installed in Windows 10 via Add / Remove Programs (ARP). The best
398 /// practice is to ensure this matches the ARP entry for the package name when it has been
399 /// installed. This should be the value of the `DisplayName` subkey for the package in the
400 /// [Windows registry]. The impact is associated with `winget upgrade` and `winget list`.
401 ///
402 /// [Windows registry]: https://learn.microsoft.com/windows/win32/msi/uninstall-registry-key
403 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
404 pub package_name: Option<PackageName>,
405
406 /// The website for the package.
407 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
408 pub package_url: Option<PackageUrl>,
409
410 /// The license governing the use and or distribution for the product.
411 ///
412 /// This could be an open source license, or a commercial license. Please note that a copyright
413 /// is not considered a license. If there is no available information on a product's license,
414 /// `Proprietary` should be the value in this field.
415 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
416 pub license: Option<License>,
417
418 /// The license website or specific web page provided the publisher or ISV.
419 ///
420 /// If there is a license website or specific web page for the package it is preferred over a
421 /// generic license page for the publisher.
422 ///
423 /// If this is a link to the license file for an open source project, it should be specific to
424 /// the version for the package. Some open source projects change their license over time.
425 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
426 pub license_url: Option<LicenseUrl>,
427
428 /// The copyright for the package.
429 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
430 pub copyright: Option<Copyright>,
431
432 /// The copyright website or specific web page provided the publisher or ISV.
433 ///
434 /// If there is a copyright website or specific web page for the package it is preferred over a
435 /// generic copyright page for the publisher.
436 ///
437 /// If this is a link to the copyright file for an open source project, it should be specific to
438 /// the version for the package. Some open source projects change their copyright over time.
439 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
440 pub copyright_url: Option<CopyrightUrl>,
441
442 /// The description for a package.
443 ///
444 /// It is intended for use in `winget show` to help a user understand what the package is.
445 ///
446 /// This should be something descriptive about what the package does, and it should not simply
447 /// state something like `<package name> installer` or `<package name> setup`.
448 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
449 pub short_description: Option<ShortDescription>,
450
451 /// The full or long description for a package.
452 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
453 pub description: Option<Description>,
454
455 /// Other common term users would search for when looking for packages.
456 ///
457 /// Tags should be pertinent to what a user might search for when looking for a specific
458 /// package.
459 ///
460 /// The best practice is to present these terms in all lower case with hyphens rather than
461 /// spaces.
462 #[cfg_attr(
463 feature = "serde",
464 serde(skip_serializing_if = "BTreeSet::is_empty", default)
465 )]
466 pub tags: BTreeSet<Tag>,
467
468 /// Any agreements a user must accept prior to download and subsequent install or upgrade.
469 ///
470 /// Agreements are only allowed in the community repository when the manifest is maintained by a
471 /// verified developer.
472 #[cfg_attr(
473 feature = "serde",
474 serde(skip_serializing_if = "BTreeSet::is_empty", default)
475 )]
476 pub agreements: BTreeSet<Agreement>,
477
478 /// The release notes for a package.
479 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
480 pub release_notes: Option<ReleaseNotes>,
481
482 /// Release notes webpage for a package.
483 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
484 pub release_notes_url: Option<ReleaseNotesUrl>,
485
486 /// The purchase url for acquiring entitlement for a package.
487 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
488 pub purchase_url: Option<Url>,
489
490 /// The notes displayed to the user upon completion of a package installation.
491 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
492 pub installation_notes: Option<InstallationNotes>,
493
494 /// Any documentation for providing software guides such as manuals and troubleshooting URLs.
495 #[cfg_attr(
496 feature = "serde",
497 serde(skip_serializing_if = "BTreeSet::is_empty", default)
498 )]
499 pub documentations: BTreeSet<Documentation>,
500
501 #[cfg_attr(
502 feature = "serde",
503 serde(skip_serializing_if = "BTreeSet::is_empty", default)
504 )]
505 pub icons: BTreeSet<Icon>,
506
507 /// The manifest type.
508 ///
509 /// Must have the value [`locale`]. The Microsoft community package repository validation
510 /// pipelines also use this value to determine appropriate validation rules when evaluating this
511 /// file.
512 ///
513 /// [`locale`]: ManifestType::Locale
514 #[cfg_attr(feature = "serde", serde(default = "ManifestType::locale"))]
515 pub manifest_type: ManifestType,
516
517 /// The manifest syntax version.
518 ///
519 /// Must have the value `1.12.0`. The Microsoft community package repository validation
520 /// pipelines also use this value to determine appropriate validation rules when evaluating this
521 /// file.
522 #[cfg_attr(feature = "serde", serde(default))]
523 pub manifest_version: ManifestVersion,
524}
525
526impl Default for LocaleManifest {
527 fn default() -> Self {
528 Self {
529 package_identifier: PackageIdentifier::default(),
530 package_version: PackageVersion::default(),
531 package_locale: LanguageTag::default(),
532 publisher: None,
533 publisher_url: None,
534 publisher_support_url: None,
535 privacy_url: None,
536 author: None,
537 package_name: None,
538 package_url: None,
539 license: None,
540 license_url: None,
541 copyright: None,
542 copyright_url: None,
543 short_description: None,
544 description: None,
545 tags: BTreeSet::default(),
546 agreements: BTreeSet::default(),
547 release_notes: None,
548 release_notes_url: None,
549 purchase_url: None,
550 installation_notes: None,
551 documentations: BTreeSet::default(),
552 icons: BTreeSet::default(),
553 manifest_type: ManifestType::Locale,
554 manifest_version: ManifestVersion::default(),
555 }
556 }
557}
558
559impl Manifest for LocaleManifest {
560 const SCHEMA: &'static str = "https://aka.ms/winget-manifest.locale.1.12.0.schema.json";
561
562 const TYPE: ManifestType = ManifestType::Locale;
563
564 fn package_identifier(&self) -> &PackageIdentifier {
565 &self.package_identifier
566 }
567
568 fn package_version(&self) -> &PackageVersion {
569 &self.package_version
570 }
571
572 fn manifest_version(&self) -> ManifestVersion {
573 self.manifest_version
574 }
575
576 fn update_manifest_version(&mut self) {
577 self.manifest_version.update();
578 }
579}