1#![allow(deprecated)]
5
6use serde::{Deserialize, Serialize};
7use serde_plain::derive_display_from_serialize;
8use tracing::trace_span;
9
10#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
11#[allow(clippy::enum_variant_names)]
12#[rustfmt::skip]
13pub enum Feature {
14 #[serde(
15 rename = "ad-countdown-timer",
16 alias = "3ae06d3a-a76b-435e-8cef-2d2008610ba2"
17 )]
18 AdCountdownTimer,
19 #[serde(
20 rename = "adaptive_bitrate",
21 alias = "abd37b14-706c-461f-8255-fa9563882af3"
22 )]
23 AdaptiveBitrate,
24 #[serde(
25 rename = "album-types",
26 alias = "1df3cd16-faf2-4d37-8349-1fcf3713bf1d"
27 )]
28 AlbumTypes,
29 #[serde(
30 rename = "allow_dvr",
31 alias = "d8810b38-ec9b-494c-8555-3df6e365dfbd"
32 )]
33 AllowDvr,
34 #[serde(
35 rename = "amazon-loop-debug",
36 alias = "d1477307-4dac-4e57-9258-252e5b908693"
37 )]
38 AmazonLoopDebug,
39 #[serde(
40 rename = "Android - Dolby Vision",
41 alias = "b227c158-e062-4ff1-95d8-8ed11cecafb1"
42 )]
43 AndroidDolbyVision,
44 #[serde(
45 rename = "Android - PiP",
46 alias = "86da2200-58db-4d78-ba46-f146ba25906b"
47 )]
48 AndroidPiP,
49 #[serde(
50 rename = "artist-tv",
51 alias = "2797e341-b062-46ed-862f-0acbba5dd522"
52 )]
53 ArtistTv,
54 #[serde(
55 rename = "avod-new-media",
56 alias = "e703655b-ee05-4e24-97e3-a138da62c425"
57 )]
58 AvodNewMedia,
59 #[serde(
60 rename = "boost-voices",
61 alias = "c2409baa-d044-45c7-b1f4-e9e7ccd2d128"
62 )]
63 BoostVoices,
64 #[serde(
65 rename = "bypass-web-navbar-upsell-modal",
66 alias = "6aaaf4fc-c55f-4042-92c8-b35f7886d249"
67 )]
68 BypassWebNavbarUpsellModal,
69 #[serde(
70 rename = "camera_upload",
71 alias = "fb34e64d-cd89-47b8-8bae-a6d20c542bae"
72 )]
73 CameraUpload,
74 #[serde(
75 rename = "chromecast-music-mp",
76 alias = "58829fc9-26b8-41f4-a6c0-90ea7a11ae24"
77 )]
78 ChromecastMusicMp,
79 #[serde(
80 rename = "client-non-destructive-comskip",
81 alias = "6ab6677b-ad9b-444f-9ca1-b8027d05b3e1"
82 )]
83 ClientNonDestructiveComskip,
84 #[serde(
85 rename = "client-radio-stations",
86 alias = "5b6190a9-77a4-477e-9fbc-c8118e35a4c1"
87 )]
88 ClientRadioStations,
89 #[serde(
90 rename = "cloud-livetv",
91 alias = "dbab9396-78ff-48f5-a5ce-c76539ed1b6e"
92 )]
93 CloudLivetv,
94 #[serde(
95 rename = "cloudsync",
96 alias = "65152b75-13a9-408a-bd30-dbd23a259183"
97 )]
98 Cloudsync,
99 #[serde(
100 rename = "collections",
101 alias = "1417df52-986e-4e4b-8dcd-3997fbc5c976"
102 )]
103 Collections,
104 #[serde(
105 rename = "community-phase0",
106 alias = "fc3e8322-5e6e-4f4a-9d71-728c6d5656bd"
107 )]
108 CommunityPhase0,
109 #[serde(
110 rename = "community-phase0-web",
111 alias = "a852775a-2b74-4624-aaa3-3d624471a537"
112 )]
113 CommunityPhase0Web,
114 #[serde(
115 rename = "companions_sonos",
116 alias = "24b4cf36-b296-4002-86b7-f1adb657e76a"
117 )]
118 CompanionsSonos,
119 #[serde(
120 rename = "conan_redirect_alpha",
121 alias = "78643fe5-d192-40c7-8e93-5ccf04c0b767"
122 )]
123 #[deprecated]
124 ConanRedirectAlpha,
125 #[serde(
126 rename = "conan_redirect_beta",
127 alias = "bfeaee4e-965a-4d24-b163-020c3c57d936"
128 )]
129 #[deprecated]
130 ConanRedirectBeta,
131 #[serde(
132 rename = "conan_redirect_nightlies",
133 alias = "98872b06-2ff3-4b71-96bc-039e2ebe7adc"
134 )]
135 #[deprecated]
136 ConanRedirectNightlies,
137 #[serde(
138 rename = "conan_redirect_nightly",
139 alias = "7e7596aa-6e2c-41d1-a460-1e13cf0b62f2"
140 )]
141 #[deprecated]
142 ConanRedirectNightly,
143 #[serde(
144 rename = "conan_redirect_public",
145 alias = "b20d91ca-1b2f-45a2-a115-c1ad24c66ac5"
146 )]
147 #[deprecated]
148 ConanRedirectPublic,
149 #[serde(
150 rename = "conan_redirect_qa",
151 alias = "16d69c53-4c40-4821-b9f3-57ca690b2d4d"
152 )]
153 #[deprecated]
154 ConanRedirectQa,
155 #[serde(
156 rename = "content_filter",
157 alias = "32cc8bf5-b425-4582-a52d-71b4f1cf436b"
158 )]
159 ContentFilter,
160 #[serde(
161 rename = "create_anonymous_users",
162 alias = "f6a0e423-1a83-418c-8448-a1c7105fd71a"
163 )]
164 CreateAnonymousUsers,
165 #[serde(
166 rename = "credits-markers",
167 alias = "926bc176-58ca-47da-b8e3-080ed14ea6ba"
168 )]
169 CreditsMarkers,
170 #[serde(
171 rename = "CU Sunset",
172 alias = "567033ef-ffee-44fb-8f90-f678077445f9"
173 )]
174 CuSunset,
175 #[serde(
176 rename = "custom-home-removal",
177 alias = "849433b0-ef60-4a71-9dd9-939bc01f5362"
178 )]
179 CustomHomeRemoval,
180 #[serde(
181 rename = "discover",
182 alias = "4a933f24-464d-4a6b-b372-9e4497abd361"
183 )]
184 Discover,
185 #[serde(
186 rename = "discover-managed-related-vod",
187 alias = "cb0e4c75-b1cb-43e9-97ea-6b9bc66c717b"
188 )]
189 DiscoverManagedRelatedVod,
190 #[serde(
191 rename = "discover-managed-user-test",
192 alias = "807d9881-a846-40c3-8d54-84fc490b7ba9"
193 )]
194 DiscoverManagedUserTest,
195 #[serde(
196 rename = "discover-services-hub",
197 alias = "ba7c4a4f-a13b-4ec0-8eb2-cd0ba2fe77f8"
198 )]
199 DiscoverServicesHub,
200 #[serde(rename = "download_certificates")]
201 DownloadCertificates,
202 #[serde(
203 rename = "downloads-gating",
204 alias = "3bfd3ccf-8c63-4dbb-8f87-9b21b402c82b"
205 )]
206 DownloadsGating,
207 #[serde(
208 rename = "drm_support",
209 alias = "34e182bd-2f62-4678-a9e9-d13b3e25019d"
210 )]
211 DrmSupport,
212 #[serde(
213 rename = "dvr",
214 alias = "e8230c74-0940-4b91-9e20-6571eb068086"
215 )]
216 Dvr,
217 #[serde(
218 rename = "dvr-block-unsupported-countries",
219 alias = "c92d4903-bc06-4715-8ce4-4a22674abac8"
220 )]
221 DvrBlockUnsupportedCountries,
222 #[serde(
223 rename = "epg-recent-channels",
224 alias = "9c982beb-c676-4d6f-a777-ff5d37ec3081"
225 )]
226 EpgRecentChannels,
227 #[serde(
228 rename = "exclude restrictions",
229 alias = "6d7be725-9a96-42c7-8af4-01e735138822"
230 )]
231 ExcludeRestrictions,
232 #[serde(
233 rename = "federated-auth",
234 alias = "5d819d02-5d04-4116-8eec-f49def4e2d6f"
235 )]
236 FederatedAuth,
237 #[serde(
238 rename = "global-continue-watching",
239 alias = "4742780c-af9d-4b44-bf5b-7b27e3369aa8"
240 )]
241 GlobalContinueWatching,
242 #[serde(
243 rename = "grandfather-sync",
244 alias = "7ee1495c-2798-4288-94e2-9cd98e67d441"
245 )]
246 GrandfatherSync,
247 #[serde(
248 rename = "guided-upgrade",
249 alias = "c9d9b7ee-fdd9-474e-b143-5039c04e9b9b"
250 )]
251 GuidedUpgrade,
252 #[serde(
253 rename = "hardware_transcoding",
254 alias = "bc8d1fca-deb0-4d0a-a6f4-12cfd681002d"
255 )]
256 HardwareTranscoding,
257 #[serde(
258 rename = "home",
259 alias = "b2403ac6-4885-4971-8b96-59353fd87c72"
260 )]
261 Home,
262 #[serde(
263 rename = "HRK_enable_EUR",
264 alias = "f1ac7a53-c524-4311-9a27-713562fc24fa"
265 )]
266 HrkEnableEur,
267 #[serde(
268 rename = "hwtranscode",
269 alias = "84a754b0-d1ca-4433-af2d-c949bf4b4936"
270 )]
271 Hwtranscode,
272 #[serde(
273 rename = "hybrid-guide",
274 alias = "c6ce2260-a19d-4fea-9f74-a52231f03924"
275 )]
276 HybridGuide,
277 #[serde(
278 rename = "imagga-v2",
279 alias = "55b9f6ed-5d26-4d2d-a436-68882a9901b5"
280 )]
281 ImaggaV2,
282 #[serde(
283 rename = "increase-password-complexity",
284 alias = "9e93f8a8-7ccd-4d15-99fa-76a158027660"
285 )]
286 IncreasePasswordComplexity,
287 #[serde(
288 rename = "intro-markers",
289 alias = "b83c8dc9-5a01-4b7a-a7c9-5870c8a6e21b"
290 )]
291 IntroMarkers,
292 #[serde(
293 rename = "ios14-privacy-banner",
294 alias = "39dbdd84-8339-4736-96a1-0eb105cc2e08"
295 )]
296 Ios14PrivacyBanner,
297 #[serde(
298 rename = "item_clusters",
299 alias = "b58d7f28-7b4a-49bb-97a7-152645505f28"
300 )]
301 ItemClusters,
302 #[serde(
303 rename = "iterable-notification-tokens",
304 alias = "81c8d5fa-8d90-4833-aa10-a31a51310e2f"
305 )]
306 IterableNotificationTokens,
307 #[serde(
308 rename = "join-discover-together",
309 alias = "f8f68869-07a5-4fc3-9359-d0b5ba9c487c"
310 )]
311 JoinDiscoverTogether,
312 #[serde(
313 rename = "join-discover-together-as-friend",
314 alias = "af866200-1116-4502-be15-f71457ce9d27"
315 )]
316 JoinDiscoverTogetherAsFriend,
317 #[serde(
318 rename = "kevin-bacon",
319 alias = "c7ae6f8f-05e6-48bb-9024-c05c1dc3c43e"
320 )]
321 KevinBacon,
322 #[serde(
323 rename = "korea-consent",
324 alias = "cb151c05-1943-408a-b37c-06f7d409d6bb"
325 )]
326 KoreaConsent,
327 #[serde(
328 rename = "lets_encrypt",
329 alias = "8536058d-e1dd-4ae7-b30f-e8b059b7cc17"
330 )]
331 LetsEncrypt,
332 #[serde(
333 rename = "lightning-dvr-pivot",
334 alias = "6b85840c-d79d-40c2-8d8f-dfc0b7d26776"
335 )]
336 LightningDvrPivot,
337 #[serde(
338 rename = "live-tv-channels-grid",
339 alias = "9eaa5152-320b-48e6-9d47-9492ba5e5b54"
340 )]
341 LiveTvChannelsGrid,
342 #[serde(
343 rename = "live-tv-grid-pagination",
344 alias = "d1b1e233-a891-45e5-935c-6114e905dbe8"
345 )]
346 LiveTvGridPagination,
347 #[serde(
348 rename = "live-tv-on-plex-subtitles",
349 alias = "0b8bf267-1acf-4f89-99eb-4afbb9d250e5"
350 )]
351 LiveTvOnPlexSubtitles,
352 #[serde(
353 rename = "live-tv-support-incomplete-segments",
354 alias = "dab501df-5d99-48ef-afc2-3e839e4ddc9a"
355 )]
356 LiveTvSupportIncompleteSegments,
357 #[serde(
358 rename = "livetv",
359 alias = "65685ff8-4375-4e4c-a806-ec1f0b4a8b7f"
360 )]
361 Livetv,
362 #[serde(
363 rename = "livetv-platform-specific",
364 alias = "de789b83-9c5e-4472-bccf-791c69e67500"
365 )]
366 LivetvPlatformSpecific,
367 #[serde(rename = "loudness")]
368 Loudness,
369 #[serde(
370 rename = "lyrics",
371 alias = "002c9f1a-2fc0-4812-b85b-0e6140f21a0f"
372 )]
373 Lyrics,
374 #[serde(
375 rename = "metadata",
376 alias = "f8ea4f37-c554-476a-8852-1cbd2912f3f6"
377 )]
378 Metadata,
379 #[serde(
380 rename = "metadata_search",
381 alias = "22b27e12-472e-4383-92ea-2ec3976d8e72"
382 )]
383 MetadataSearch,
384 #[serde(
385 rename = "music",
386 alias = "e7cea823-02e5-48c4-a501-d37b82bf132f"
387 )]
388 Music,
389 #[serde(
390 rename = "music-analysis",
391 alias = "8fd37970-6e4e-4f00-a64a-e70b52f18e94"
392 )]
393 MusicAnalysis,
394 #[serde(
395 rename = "music_preview",
396 alias = "8e8dd5c8-14a4-4208-97d4-623e09191774"
397 )]
398 MusicPreview,
399 #[serde(
400 rename = "music_videos",
401 alias = "1844737f-1a87-45c3-ab20-01435959e63c"
402 )]
403 MusicVideos,
404 #[serde(
405 rename = "news-provider-sunset-modal",
406 alias = "b77e6744-c18d-415a-8e7c-7aac5d7a7750"
407 )]
408 NewsProviderSunsetModal,
409 #[serde(
410 rename = "nominatim",
411 alias = "0de6151c-e0dd-47c8-a81e-1acb977c7f0f"
412 )]
413 Nominatim,
414 #[serde(
415 rename = "nonAnonymousAccount",
416 alias = "3dd35df0-3e4a-4e74-9ba8-2baeda83a733"
417 )]
418 NonAnonymousAccount,
419 #[serde(
420 rename = "optimize-server-users-endpoint",
421 alias = "ddd730e1-a0a0-429f-a7d3-7c5001d24497"
422 )]
423 #[deprecated]
424 OptimizeServerUsersEndpoint,
425 #[serde(
426 rename = "parental-controls",
427 alias = "73d0bba4-a6ba-4114-bac3-3039c12e08fb"
428 )]
429 ParentalControls,
430 #[serde(
431 rename = "pass",
432 alias = "82999dd3-a2be-482e-9f44-357879b4f603"
433 )]
434 Pass,
435 #[serde(
436 rename = "people-pages",
437 alias = "f4fe27db-7292-4e13-98b6-f3ff9b5ed5fe"
438 )]
439 PeoplePages,
440 #[serde(
441 rename = "people-pages-pms",
442 alias = "652968f4-d474-4e04-a1cf-2dd1eaeb488a"
443 )]
444 PeoplePagesPms,
445 #[serde(rename = "photo_autotags")]
446 PhotoAutotags,
447 #[serde(
448 rename = "photos-favorites",
449 alias = "96cac76e-c5bc-4596-87eb-4fdfef9aaa11"
450 )]
451 PhotosFavorites,
452 #[serde(
453 rename = "photos-metadata-edition",
454 alias = "2ea0e464-ea4f-4be2-97c1-ce6ed4b377dd"
455 )]
456 PhotosMetadataEdition,
457 #[serde(
458 rename = "photos-v5",
459 alias = "0a348865-4f87-46dc-8bb2-f37637975724"
460 )]
461 #[deprecated]
462 PhotosV5,
463 #[serde(
464 rename = "photosV6-edit",
465 alias = "850f3d1e-3f38-44c1-9c0c-e3c9127b8b5a"
466 )]
467 PhotosV6Edit,
468 #[serde(
469 rename = "photosV6-tv-albums",
470 alias = "3a2b0cb6-1519-4431-98e2-823c248c70eb"
471 )]
472 PhotosV6TvAlbums,
473 #[serde(
474 rename = "podcasts",
475 alias = "1841971c-6be5-40e6-a211-7e189d767a78"
476 )]
477 Podcasts,
478 #[serde(
479 rename = "premium-dashboard",
480 alias = "222020fb-1504-492d-af33-a0b80a49558a"
481 )]
482 PremiumDashboard,
483 #[serde(
484 rename = "premium_music_metadata",
485 alias = "d413fb56-de7b-40e4-acd0-f3dbb7c9e104"
486 )]
487 PremiumMusicMetadata,
488 #[serde(
489 rename = "promoted-grid-channel-filters",
490 alias = "a0a78867-6b26-446f-9c3f-df4edf831259"
491 )]
492 PromotedGridChannelFilters,
493 #[serde(
494 rename = "radio",
495 alias = "300231e0-69aa-4dce-97f4-52d8c00e3e8c"
496 )]
497 Radio,
498 #[serde(
499 rename = "retro-games",
500 alias = "4e27cf82-9fb6-4ebe-8e10-c48bfe6fbbb6"
501 )]
502 #[deprecated]
503 RetroGames,
504 #[serde(
505 rename = "retro-games-plex-tv",
506 alias = "a4bc568b-477f-4f36-894b-49e19f34353f"
507 )]
508 #[deprecated]
509 RetroGamesPlexTv,
510 #[serde(
511 rename = "save-to-library",
512 alias = "644c4466-05fa-45e0-a478-c594cf81778f"
513 )]
514 SaveToLibrary,
515 #[serde(
516 rename = "scrobbling-service",
517 alias = "ccef9d3a-537a-43d9-8161-4c7113c6e2bb"
518 )]
519 ScrobblingService,
520 #[serde(
521 rename = "scrobbling-service-plex-tv",
522 alias = "7b392594-6949-4736-9894-e57a9dfe4037"
523 )]
524 ScrobblingServicePlexTv,
525 #[serde(rename = "server-manager")]
526 ServerManager,
527 #[serde(
528 rename = "session_bandwidth_restrictions",
529 alias = "05690239-443e-43fb-bc1a-95b5d916ca63"
530 )]
531 SessionBandwidthRestrictions,
532 #[serde(
533 rename = "session_kick",
534 alias = "4ca03b04-54c1-4f9f-aea2-f813ae48f317"
535 )]
536 SessionKick,
537 #[serde(rename = "shared-radio")]
538 SharedRadio,
539 #[serde(
540 rename = "signin_notification",
541 alias = "1b3a63e4-c2f4-4011-a181-2343d3a97ef7"
542 )]
543 SigninNotification,
544 #[serde(
545 rename = "signin_with_apple",
546 alias = "b5874ecb-6610-47b2-8906-1b5a897acb02"
547 )]
548 SigninWithApple,
549 #[serde(
550 rename = "silence-removal",
551 alias = "a6e0a154-4735-4cbb-a6ec-7a0a146c8216"
552 )]
553 SilenceRemoval,
554 #[serde(
555 rename = "singleitemsharing",
556 alias = "62b1e357-5450-41d8-9b60-c7705f750849"
557 )]
558 Singleitemsharing,
559 #[serde(
560 rename = "sleep-timer",
561 alias = "c5adf9dc-af13-4a85-a24b-98de6fa2f595"
562 )]
563 SleepTimer,
564 #[serde(
565 rename = "sonos-client-feature",
566 alias = "8a9471c4-13bd-435a-b5b8-4ca6e423f355"
567 )]
568 SonosClientFeature,
569 #[serde(
570 rename = "spotlight-style-hub",
571 alias = "579156cf-0664-45b4-8b7b-dda400ac3e26"
572 )]
573 SpotlightStyleHub,
574 #[serde(
575 rename = "spring_serve_ad_provider",
576 alias = "fec722a0-a6d4-4fbd-96dc-4ffb02b072c5"
577 )]
578 SpringServeAdProvider,
579 #[serde(
580 rename = "Subtitles on Demand",
581 alias = "bb50c92f-b412-44fe-8d8a-b1684f212a44"
582 )]
583 SubtitlesOnDemand,
584 #[serde(
585 rename = "sweet-fades",
586 alias = "95149521-f64b-46ea-825c-9114e56afd2c"
587 )]
588 SweetFades,
589 #[serde(
590 rename = "sync",
591 alias = "9dc1df45-fb45-4be1-9ab2-eb23eb57f082"
592 )]
593 Sync,
594 #[serde(
595 rename = "Sync v3",
596 alias = "67c80530-eae3-4500-a9fa-9b6947d0f6d1"
597 )]
598 SyncV3,
599 #[serde(
600 rename = "trailers",
601 alias = "6380e085-02fe-43b5-8bff-380fa4f2423c"
602 )]
603 Trailers,
604 #[serde(
605 rename = "transcoder_cache",
606 alias = "a3d2d5c4-46a0-436e-a2d6-80d26f32b369"
607 )]
608 TranscoderCache,
609 #[serde(
610 rename = "TREBLE-show-features",
611 alias = "85ebfb7b-77fb-4afd-bb1a-2fe2fefdddbe"
612 )]
613 TrebleShowFeatures,
614 #[serde(
615 rename = "tunefind-clients",
616 alias = "07f804e6-28e6-4beb-b5c3-f2aefc88b938"
617 )]
618 TunefindClients,
619 #[serde(
620 rename = "tunefind-vod",
621 alias = "50a1cfe9-dac1-4722-aee8-cc22e9758dd6"
622 )]
623 TunefindVod,
624 #[serde(
625 rename = "tuner-sharing",
626 alias = "4b522f91-ae89-4f62-af9c-76f44d8ef61c"
627 )]
628 TunerSharing,
629 #[serde(
630 rename = "two-factor-authentication",
631 alias = "06d14b9e-2af8-4c2b-a4a1-ea9d5c515824"
632 )]
633 TwoFactorAuthentication,
634 #[serde(
635 rename = "two-factor-authentication-clients",
636 alias = "20824f5c-6dd9-4655-9970-e7701a73c02a"
637 )]
638 TwoFactorAuthenticationClients,
639 #[serde(
640 rename = "type-first",
641 alias = "d14556be-ae6d-4407-89d0-b83953f4789a"
642 )]
643 TypeFirst,
644 #[serde(
645 rename = "ultrablur",
646 alias = "cec2152f-321a-4c24-8c6d-c2b35a624389"
647 )]
648 Ultrablur,
649 #[serde(
650 rename = "universal-search",
651 alias = "8b46de05-1f96-4278-87b3-010ba5b1e386"
652 )]
653 UniversalSearch,
654 #[serde(
655 rename = "universal-search-live-tv",
656 alias = "cce9af5d-7b44-4119-a6b1-108fd0db725c"
657 )]
658 UniversalSearchLiveTv,
659 #[serde(
660 rename = "universal-watchlist",
661 alias = "d9528436-ee7c-42e3-ab7b-814f85ef74b4"
662 )]
663 UniversalWatchlist,
664 #[serde(
665 rename = "unsupportedtuners",
666 alias = "b46d16ae-cbd6-4226-8ee9-ab2b27e5dd42"
667 )]
668 Unsupportedtuners,
669 #[serde(
670 rename = "upgrade-3ds2",
671 alias = "547514ab-3284-46e5-af77-bbaff247e3fc"
672 )]
673 Upgrade3ds2,
674 #[serde(
675 rename = "user-profile-whats-new",
676 alias = "90138784-37a0-4a6b-87f6-1146d6c628e6"
677 )]
678 #[deprecated]
679 UserProfileWhatsNew,
680 #[serde(
681 rename = "users-and-sharing",
682 alias = "096ab4b8-04d2-41f4-9602-f1d5b9e8c7cc"
683 )]
684 UsersAndSharing,
685 #[serde(
686 rename = "visualizers",
687 alias = "1dd846ed-7cde-4dc5-8ef6-53d3ce8c4e9d"
688 )]
689 Visualizers,
690 #[serde(
691 rename = "vod",
692 alias = "cc9bea3b-11ab-4402-a222-4958bb129cab"
693 )]
694 Vod,
695 #[serde(
696 rename = "vod_channels",
697 alias = "5050545e-95c6-4a25-b94e-1fe5a5a603d0"
698 )]
699 VodChannels,
700 #[serde(
701 rename = "vod_cloudflare",
702 alias = "68747f3a-ce13-46ce-9274-1e0544c9f500"
703 )]
704 VodCloudflare,
705 #[serde(
706 rename = "vod_subtitles",
707 alias = "ed374ad1-1d36-4396-8794-f710011e4fed"
708 )]
709 VodSubtitles,
710 #[serde(
711 rename = "volume-leveling",
712 alias = "bbf73498-4912-4d80-9560-47c4fe212cec"
713 )]
714 VolumeLeveling,
715 #[serde(
716 rename = "watch-together-20200520",
717 alias = "65faa2d0-f57e-4c63-a6b6-f1baa48951b1"
718 )]
719 WatchTogether20200520,
720 #[serde(
721 rename = "watch-together-invite",
722 alias = "f83450e2-759a-4de4-8b31-e4a163896d43"
723 )]
724 WatchTogetherInvite,
725 #[serde(
726 rename = "watchlist",
727 alias = "f0c452ce-11e7-465f-be04-5fb0bf4bec48"
728 )]
729 Watchlist,
730 #[serde(
731 rename = "watchlist-rss",
732 alias = "f0f40559-a43a-4b8f-85ef-bdb1de1a912a"
733 )]
734 WatchlistRss,
735 #[serde(
736 rename = "watchlist-source",
737 alias = "edd6039a-137c-4ace-b5d5-4e111ce9690b"
738 )]
739 WatchlistSource,
740 #[serde(
741 rename = "web-desktop-gracenote-banner",
742 alias = "13056a62-9bd2-47cf-aba9-bab00095fd08"
743 )]
744 WebDesktopGracenoteBanner,
745 #[serde(
746 rename = "web-desktop-live-tv-chromecast-remote-player",
747 alias = "b737075d-a6c5-4e8a-8ee9-7dc72d984062"
748 )]
749 WebDesktopLiveTvChromecastRemotePlayer,
750 #[serde(
751 rename = "web-desktop-v4-dvr-setup",
752 alias = "f8484f94-92a8-4ca4-9f43-e83ab3f586c7"
753 )]
754 WebDesktopV4DvrSetup,
755 #[serde(
756 rename = "web-desktop-v4-home",
757 alias = "29bca3b8-e40b-4c69-b71c-f88047240f9b"
758 )]
759 WebDesktopV4Home,
760 #[serde(
761 rename = "web-desktop-v4-pre-plays",
762 alias = "591895c1-8c60-4eab-8096-3594bb190257"
763 )]
764 WebDesktopV4PrePlays,
765 #[serde(
766 rename = "web-log-viewer",
767 alias = "740a75d2-6dba-4317-ba68-ed3d619d4c7a"
768 )]
769 WebLogViewer,
770 #[serde(
771 rename = "web_server_dashboard",
772 alias = "5e2a89ec-fb26-4234-b66e-14d37f35dff2"
773 )]
774 WebServerDashboard,
775 #[serde(
776 rename = "web-share-v2",
777 alias = "73c73f05-7131-41cd-86d7-b91301684bfe"
778 )]
779 WebShareV2,
780 #[serde(
781 rename = "webhooks",
782 alias = "6f82ca43-6117-4e55-ae0e-5ea3b3e99a96"
783 )]
784 Webhooks,
785 #[serde(
786 rename = "webshows",
787 alias = "55e1398c-930f-41c1-bead-f5c2e471bb25"
788 )]
789 Webshows,
790 #[serde(
791 rename = "where-to-watch-clients",
792 alias = "e4f02866-841f-4ceb-a30c-0a0e68fb874d"
793 )]
794 WhereToWatchClients,
795 UnknownUuid(String),
796 #[cfg(not(feature = "tests_deny_unknown_fields"))]
797 #[serde(other)]
798 UnknownValue,
799}
800
801impl ::std::str::FromStr for Feature {
802 type Err = serde_plain::Error;
803 fn from_str(s: &str) -> ::std::result::Result<Feature, Self::Err> {
804 let span = trace_span!("Feature::deserialize");
805 let _span_enter = span.enter();
806
807 let result = serde_plain::from_str(s);
808
809 #[cfg(not(feature = "tests_deny_unknown_fields"))]
810 let is_unknown_value = matches!(result, Ok(Feature::UnknownValue));
811 #[cfg(feature = "tests_deny_unknown_fields")]
812 let is_unknown_value = result.is_err();
813
814 if is_unknown_value
815 && s.len() == 36
816 && s.as_bytes()[8] == b'-'
817 && s.as_bytes()[13] == b'-'
818 && s.as_bytes()[18] == b'-'
819 && s.as_bytes()[23] == b'-'
820 {
821 return Ok(Feature::UnknownUuid(s.to_string()));
822 }
823
824 result
825 }
826}
827derive_display_from_serialize!(Feature);
828
829#[cfg(test)]
830mod test {
831 use crate::media_container::server::Feature;
832 use std::str::FromStr;
833
834 #[cfg(not(feature = "tests_deny_unknown_fields"))]
835 #[plex_api_test_helper::offline_test]
836 fn test_unknown_feature() {
837 let f = Feature::from_str("unknown_value").unwrap();
838 assert_eq!(f, Feature::UnknownValue);
839 }
840
841 #[plex_api_test_helper::offline_test]
842 fn test_unknown_feature_uuid() {
843 let f = Feature::from_str("cc9bea3b-aaaa-bbbb-cccc-4958bb129caa").unwrap();
844 assert_eq!(
845 f,
846 Feature::UnknownUuid("cc9bea3b-aaaa-bbbb-cccc-4958bb129caa".to_owned())
847 );
848 }
849
850 #[plex_api_test_helper::offline_test]
851 fn test_known_feature() {
852 let f = Feature::from_str("webhooks").unwrap();
853 assert_eq!(f, Feature::Webhooks);
854
855 let f = Feature::from_str("6f82ca43-6117-4e55-ae0e-5ea3b3e99a96").unwrap();
856 assert_eq!(f, Feature::Webhooks);
857 }
858
859 #[plex_api_test_helper::offline_test]
860 fn test_known_deprecated_feature() {
861 let f = Feature::from_str("optimize-server-users-endpoint").unwrap();
862 assert_eq!(f, Feature::OptimizeServerUsersEndpoint);
863
864 let f = Feature::from_str("ddd730e1-a0a0-429f-a7d3-7c5001d24497").unwrap();
865 assert_eq!(f, Feature::OptimizeServerUsersEndpoint);
866 }
867}