Skip to main content

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}