├── CHANGELOG.md ├── .github ├── dependabot.yml └── workflows │ ├── publish.yml │ └── test.yml ├── Cargo.toml ├── LICENSE-MIT ├── README.md ├── src └── lib.rs └── LICENSE-APACHE /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 0.1.3 2 | ----- 3 | - Relicensed project under terms of `Apache-2.0 OR MIT` 4 | 5 | 6 | 0.1.2 7 | ----- 8 | - Added support for struct enum variants 9 | - Tagged more functions and methods as `#[inline]` 10 | - Switched to using GitHub Actions as CI provider 11 | - Bumped minimum supported Rust version to `1.57` 12 | 13 | 14 | 0.1.1 15 | ----- 16 | - Added support for newtype structs, newtype enum variants, and tuple 17 | enum variants to `to_variant_name` 18 | 19 | 20 | 0.1.0 21 | ----- 22 | - Initial release 23 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Daniel Mueller 2 | # SPDX-License-Identifier: (Apache-2.0 OR MIT) 3 | 4 | # Please see the documentation for all configuration options: 5 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 6 | 7 | version: 2 8 | updates: 9 | - package-ecosystem: github-actions 10 | rebase-strategy: auto 11 | directory: / 12 | schedule: 13 | interval: daily 14 | - package-ecosystem: cargo 15 | versioning-strategy: auto 16 | directory: / 17 | schedule: 18 | interval: daily 19 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023-2024 Daniel Mueller 2 | # SPDX-License-Identifier: (Apache-2.0 OR MIT) 3 | 4 | name: Publish 5 | 6 | on: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | test: 11 | uses: ./.github/workflows/test.yml 12 | publish: 13 | needs: [test] 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v5 17 | - uses: dtolnay/rust-toolchain@stable 18 | - name: Publish serde_variant 19 | run: cargo publish --locked --no-verify --token "${CARGO_REGISTRY_TOKEN}" 20 | env: 21 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 22 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_variant" 3 | version = "0.1.3" 4 | authors = ["Daniel Mueller "] 5 | edition = "2018" 6 | license = "Apache-2.0 OR MIT" 7 | homepage = "https://github.com/d-e-s-o/serde_variant" 8 | repository = "https://github.com/d-e-s-o/serde_variant.git" 9 | readme = "README.md" 10 | categories = ["value-formatting", "encoding", "parsing", "data-structures"] 11 | keywords = ["serialization", "serde", "enum", "variants"] 12 | description = """ 13 | Retrieve serde provided variant names for enum objects. 14 | """ 15 | 16 | [dependencies] 17 | serde = {version = "1.0", default-features = false} 18 | 19 | [dev-dependencies] 20 | serde = {version = "1.0", default-features = false, features = ["derive"]} 21 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Daniel Müller 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023-2024 Daniel Mueller 2 | # SPDX-License-Identifier: (Apache-2.0 OR MIT) 3 | 4 | name: Test 5 | 6 | on: 7 | pull_request: 8 | push: 9 | workflow_call: 10 | 11 | env: 12 | CARGO_TERM_COLOR: always 13 | RUST_BACKTRACE: 1 14 | # Build without debug information enabled to decrease compilation time 15 | # and binary sizes in CI. This option is assumed to only have marginal 16 | # effects on the generated code, likely only in terms of section 17 | # arrangement. See 18 | # https://doc.rust-lang.org/cargo/reference/environment-variables.html 19 | # https://doc.rust-lang.org/rustc/codegen-options/index.html#debuginfo 20 | RUSTFLAGS: '-C debuginfo=0' 21 | 22 | jobs: 23 | test: 24 | name: Build and test [${{ matrix.rust }}, ${{ matrix.profile }}] 25 | runs-on: ubuntu-latest 26 | strategy: 27 | fail-fast: false 28 | matrix: 29 | rust: [1.57.0, stable] 30 | profile: [dev, release] 31 | steps: 32 | - uses: actions/checkout@v5 33 | - uses: dtolnay/rust-toolchain@master 34 | with: 35 | toolchain: ${{ matrix.rust }} 36 | - name: Build ${{ matrix.profile }} 37 | run: | 38 | cargo build --profile=${{ matrix.profile }} --bins --tests --examples 39 | cargo test --profile=${{ matrix.profile }} 40 | clippy: 41 | name: Lint with clippy 42 | runs-on: ubuntu-latest 43 | steps: 44 | - uses: actions/checkout@v5 45 | - uses: dtolnay/rust-toolchain@stable 46 | - run: 47 | cargo clippy --all-targets --all-features -- -D warnings 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![pipeline](https://github.com/d-e-s-o/serde_variant/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/d-e-s-o/serde_variant/actions/workflows/test.yml) 2 | [![crates.io](https://img.shields.io/crates/v/serde_variant.svg)](https://crates.io/crates/serde_variant) 3 | [![Docs](https://docs.rs/serde_variant/badge.svg)](https://docs.rs/serde_variant) 4 | [![rustc](https://img.shields.io/badge/rustc-1.57+-blue.svg)](https://blog.rust-lang.org/2021/12/02/Rust-1.57.0.html) 5 | 6 | serde_variant 7 | ============= 8 | 9 | - [Documentation][docs-rs] 10 | - [Changelog](CHANGELOG.md) 11 | 12 | So you have just carefully defined your `enum` to be serialized and 13 | deserialized using [`serde`][serde] as you intended and now you need an 14 | additional `FromStr` or `Display` implementation that uses the same 15 | names for `enum` variants as `serde` uses? You are reluctant to 16 | duplicate all those definitions in two places? 17 | 18 | **serde_variant** is a crate that allows you to retrieve back the 19 | identifier of any `enum` variant passed to it. 20 | 21 | 22 | Usage 23 | ----- 24 | 25 | The crate provides a single function, `to_variant_name`, that retrieves 26 | the name of a passed in `enum` variant. For example: 27 | ```rust 28 | use serde_variant::to_variant_name; 29 | 30 | #[derive(Serialize)] 31 | enum Foo { 32 | Var1, 33 | #[serde(rename = "VAR2")] 34 | Var2, 35 | } 36 | 37 | assert_eq!(to_variant_name(&Foo::Var1).unwrap(), "Var1"); 38 | assert_eq!(to_variant_name(&Foo::Var2).unwrap(), "VAR2"); 39 | ``` 40 | 41 | [docs-rs]: https://docs.rs/crate/serde_variant 42 | [serde]: https://crates.io/crates/serde 43 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020-2025 Daniel Mueller 2 | // SPDX-License-Identifier: (Apache-2.0 OR MIT) 3 | 4 | use std::error::Error; 5 | use std::fmt::Display; 6 | use std::fmt::Formatter; 7 | use std::fmt::Result as FmtResult; 8 | 9 | use serde::ser::Error as SerdeError; 10 | use serde::ser::Impossible; 11 | use serde::ser::SerializeStructVariant; 12 | use serde::ser::SerializeTupleVariant; 13 | use serde::Serialize; 14 | use serde::Serializer as SerdeSerializer; 15 | 16 | 17 | /// An error emitted when attempting to perform an unsupported 18 | /// operation. 19 | #[derive(Clone, Debug, PartialEq)] 20 | pub struct UnsupportedType { 21 | /// The method that is not supported. 22 | method: String, 23 | } 24 | 25 | impl Display for UnsupportedType { 26 | #[inline] 27 | fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult { 28 | write!(fmt, "{} is not supported", self.method) 29 | } 30 | } 31 | 32 | impl Error for UnsupportedType {} 33 | 34 | impl SerdeError for UnsupportedType { 35 | #[inline] 36 | fn custom(method: T) -> Self 37 | where 38 | T: Display, 39 | { 40 | Self { 41 | method: method.to_string(), 42 | } 43 | } 44 | } 45 | 46 | 47 | /// Convert an enum variant into its name. 48 | /// 49 | /// Note that only enum variants may be converted here and all other 50 | /// types will result in an `UnsupportedType` error. 51 | #[inline] 52 | pub fn to_variant_name(value: &T) -> Result<&'static str, UnsupportedType> 53 | where 54 | T: Serialize, 55 | { 56 | let mut serializer = Serializer {}; 57 | value.serialize(&mut serializer) 58 | } 59 | 60 | 61 | /// A serializer for tuple enum variants. 62 | struct TupleVariantSerializer(&'static str); 63 | 64 | impl SerializeTupleVariant for TupleVariantSerializer { 65 | type Ok = &'static str; 66 | type Error = UnsupportedType; 67 | 68 | #[inline] 69 | fn serialize_field(&mut self, _value: &T) -> Result<(), Self::Error> 70 | where 71 | T: Serialize + ?Sized, 72 | { 73 | Ok(()) 74 | } 75 | 76 | #[inline] 77 | fn end(self) -> Result { 78 | Ok(self.0) 79 | } 80 | } 81 | 82 | /// A serializer for struct enum variants. 83 | struct StructVariantSerializer(&'static str); 84 | 85 | impl SerializeStructVariant for StructVariantSerializer { 86 | type Ok = &'static str; 87 | type Error = UnsupportedType; 88 | 89 | #[inline] 90 | fn serialize_field(&mut self, _key: &'static str, _value: &T) -> Result<(), Self::Error> 91 | where 92 | T: ?Sized + Serialize, 93 | { 94 | Ok(()) 95 | } 96 | 97 | #[inline] 98 | fn end(self) -> Result { 99 | Ok(self.0) 100 | } 101 | } 102 | 103 | 104 | /// A serde serializer that converts an enum variant into the variant's 105 | /// name. 106 | struct Serializer {} 107 | 108 | impl SerdeSerializer for &mut Serializer { 109 | type Ok = &'static str; 110 | type Error = UnsupportedType; 111 | 112 | type SerializeSeq = Impossible; 113 | type SerializeTuple = Impossible; 114 | type SerializeTupleStruct = Impossible; 115 | type SerializeTupleVariant = TupleVariantSerializer; 116 | type SerializeMap = Impossible; 117 | type SerializeStruct = Impossible; 118 | type SerializeStructVariant = StructVariantSerializer; 119 | 120 | #[inline] 121 | fn serialize_bool(self, _v: bool) -> Result { 122 | Err(Self::Error::custom("serialize_bool")) 123 | } 124 | 125 | #[inline] 126 | fn serialize_i8(self, _v: i8) -> Result { 127 | Err(Self::Error::custom("serialize_i8")) 128 | } 129 | 130 | #[inline] 131 | fn serialize_i16(self, _v: i16) -> Result { 132 | Err(Self::Error::custom("serialize_i16")) 133 | } 134 | 135 | #[inline] 136 | fn serialize_i32(self, _v: i32) -> Result { 137 | Err(Self::Error::custom("serialize_i32")) 138 | } 139 | 140 | #[inline] 141 | fn serialize_i64(self, _v: i64) -> Result { 142 | Err(Self::Error::custom("serialize_i64")) 143 | } 144 | 145 | #[inline] 146 | fn serialize_u8(self, _v: u8) -> Result { 147 | Err(Self::Error::custom("serialize_u8")) 148 | } 149 | 150 | #[inline] 151 | fn serialize_u16(self, _v: u16) -> Result { 152 | Err(Self::Error::custom("serialize_u16")) 153 | } 154 | 155 | #[inline] 156 | fn serialize_u32(self, _v: u32) -> Result { 157 | Err(Self::Error::custom("serialize_u32")) 158 | } 159 | 160 | #[inline] 161 | fn serialize_u64(self, _v: u64) -> Result { 162 | Err(Self::Error::custom("serialize_u64")) 163 | } 164 | 165 | #[inline] 166 | fn serialize_f32(self, _v: f32) -> Result { 167 | Err(Self::Error::custom("serialize_f32")) 168 | } 169 | 170 | #[inline] 171 | fn serialize_f64(self, _v: f64) -> Result { 172 | Err(Self::Error::custom("serialize_f64")) 173 | } 174 | 175 | #[inline] 176 | fn serialize_char(self, _v: char) -> Result { 177 | Err(Self::Error::custom("serialize_char")) 178 | } 179 | 180 | #[inline] 181 | fn serialize_str(self, _v: &str) -> Result { 182 | Err(Self::Error::custom("serialize_str")) 183 | } 184 | 185 | #[inline] 186 | fn serialize_bytes(self, _v: &[u8]) -> Result { 187 | Err(Self::Error::custom("serialize_bytes")) 188 | } 189 | 190 | #[inline] 191 | fn serialize_none(self) -> Result { 192 | Err(Self::Error::custom("serialize_none")) 193 | } 194 | 195 | #[inline] 196 | fn serialize_some(self, value: &T) -> Result 197 | where 198 | T: ?Sized + Serialize, 199 | { 200 | value.serialize(self) 201 | } 202 | 203 | #[inline] 204 | fn serialize_unit(self) -> Result { 205 | Err(Self::Error::custom("serialize_unit")) 206 | } 207 | 208 | #[inline] 209 | fn serialize_unit_struct(self, _name: &'static str) -> Result { 210 | Err(Self::Error::custom("serialize_unit_struct")) 211 | } 212 | 213 | #[inline] 214 | fn serialize_unit_variant( 215 | self, 216 | _name: &'static str, 217 | _variant_index: u32, 218 | variant: &'static str, 219 | ) -> Result { 220 | Ok(variant) 221 | } 222 | 223 | #[inline] 224 | fn serialize_newtype_struct( 225 | self, 226 | name: &'static str, 227 | _value: &T, 228 | ) -> Result 229 | where 230 | T: ?Sized + Serialize, 231 | { 232 | Ok(name) 233 | } 234 | 235 | #[inline] 236 | fn serialize_newtype_variant( 237 | self, 238 | _name: &'static str, 239 | _variant_index: u32, 240 | variant: &'static str, 241 | _value: &T, 242 | ) -> Result 243 | where 244 | T: ?Sized + Serialize, 245 | { 246 | Ok(variant) 247 | } 248 | 249 | #[inline] 250 | fn serialize_seq(self, _len: Option) -> Result { 251 | Err(Self::Error::custom("serialize_seq")) 252 | } 253 | 254 | #[inline] 255 | fn serialize_tuple(self, _len: usize) -> Result { 256 | Err(Self::Error::custom("serialize_tuple")) 257 | } 258 | 259 | #[inline] 260 | fn serialize_tuple_struct( 261 | self, 262 | _name: &'static str, 263 | _len: usize, 264 | ) -> Result { 265 | Err(Self::Error::custom("serialize_tuple_struct")) 266 | } 267 | 268 | #[inline] 269 | fn serialize_tuple_variant( 270 | self, 271 | _name: &'static str, 272 | _variant_index: u32, 273 | variant: &'static str, 274 | _len: usize, 275 | ) -> Result { 276 | Ok(TupleVariantSerializer(variant)) 277 | } 278 | 279 | #[inline] 280 | fn serialize_map(self, _len: Option) -> Result { 281 | Err(Self::Error::custom("serialize_map")) 282 | } 283 | 284 | #[inline] 285 | fn serialize_struct( 286 | self, 287 | _name: &'static str, 288 | _len: usize, 289 | ) -> Result { 290 | Err(Self::Error::custom("serialize_struct")) 291 | } 292 | 293 | #[inline] 294 | fn serialize_struct_variant( 295 | self, 296 | _name: &'static str, 297 | _variant_index: u32, 298 | variant: &'static str, 299 | _len: usize, 300 | ) -> Result { 301 | Ok(StructVariantSerializer(variant)) 302 | } 303 | 304 | #[inline] 305 | fn collect_str(self, _value: &T) -> Result 306 | where 307 | T: ?Sized, 308 | { 309 | Err(Self::Error::custom("collect_str")) 310 | } 311 | } 312 | 313 | 314 | #[cfg(test)] 315 | mod tests { 316 | use super::*; 317 | 318 | #[test] 319 | fn unit_variant_names() { 320 | #[derive(Serialize)] 321 | enum Foo { 322 | Var1, 323 | #[serde(rename = "VAR2")] 324 | Var2, 325 | } 326 | 327 | assert_eq!(to_variant_name(&Foo::Var1).unwrap(), "Var1"); 328 | assert_eq!(to_variant_name(&Foo::Var2).unwrap(), "VAR2"); 329 | } 330 | 331 | #[test] 332 | fn newtype_variant_names() { 333 | #[derive(Serialize)] 334 | enum Foo { 335 | Var1(()), 336 | #[serde(rename = "VAR2")] 337 | Var2(u32), 338 | } 339 | 340 | assert_eq!(to_variant_name(&Foo::Var1(())).unwrap(), "Var1"); 341 | assert_eq!(to_variant_name(&Foo::Var2(42)).unwrap(), "VAR2"); 342 | } 343 | 344 | #[test] 345 | fn tuple_variant_names() { 346 | #[derive(Serialize)] 347 | enum Foo { 348 | BAz((), u64), 349 | #[serde(rename = "VAR")] 350 | Var((), (), ()), 351 | } 352 | 353 | assert_eq!(to_variant_name(&Foo::BAz((), 1337)).unwrap(), "BAz"); 354 | assert_eq!(to_variant_name(&Foo::Var((), (), ())).unwrap(), "VAR"); 355 | } 356 | 357 | #[test] 358 | fn newtype_struct() { 359 | #[derive(Serialize)] 360 | struct Bar(u64); 361 | 362 | assert_eq!(to_variant_name(&Bar(42)).unwrap(), "Bar"); 363 | } 364 | 365 | /// Check that we can correctly retrieve names of enum struct 366 | /// variants. 367 | #[test] 368 | fn struct_variant_names() { 369 | #[derive(Serialize)] 370 | enum Foo { 371 | Baz { 372 | i: i32, 373 | }, 374 | #[serde(rename = "VAR")] 375 | Var { 376 | i: i32, 377 | }, 378 | } 379 | 380 | assert_eq!(to_variant_name(&Foo::Baz { i: 0 }).unwrap(), "Baz"); 381 | assert_eq!(to_variant_name(&Foo::Var { i: 0 }).unwrap(), "VAR"); 382 | } 383 | } 384 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | https://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | https://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------