1use std::collections::HashMap;
6use std::fmt;
7
8#[derive(Debug, Clone)]
11pub struct KeywordInstanceData {
12 pub keyword: Keyword,
14 pub original: String,
16 pub intrinsic: bool,
18 pub idx: i64,
20}
21
22impl KeywordInstanceData {
23 pub fn new(keyword: Keyword, original: String) -> Self {
25 Self {
26 keyword,
27 original,
28 intrinsic: false,
29 idx: -1,
30 }
31 }
32}
33
34#[derive(Debug, Clone)]
38pub struct KeywordInstance {
39 pub data: KeywordInstanceData,
41 pub triggers: Vec<String>,
43 pub replacements: Vec<String>,
45 pub spell_abilities: Vec<String>,
47 pub static_abilities: Vec<String>,
49 pub svars: HashMap<String, String>,
51}
52
53impl KeywordInstance {
54 pub fn new(data: KeywordInstanceData) -> Self {
56 Self {
57 data,
58 triggers: Vec::new(),
59 replacements: Vec::new(),
60 spell_abilities: Vec::new(),
61 static_abilities: Vec::new(),
62 svars: HashMap::new(),
63 }
64 }
65
66 pub fn create_traits(&mut self) {
70 self.triggers.clear();
71 self.replacements.clear();
72 self.spell_abilities.clear();
73 self.static_abilities.clear();
74 }
75
76 pub fn add_trigger(&mut self, trigger: String) {
79 self.triggers.push(trigger);
80 }
81
82 pub fn add_replacement(&mut self, replacement: String) {
85 self.replacements.push(replacement);
86 }
87
88 pub fn add_spell_ability(&mut self, ability: String) {
91 self.spell_abilities.push(ability);
92 }
93
94 pub fn add_static_ability(&mut self, static_ab: String) {
97 self.static_abilities.push(static_ab);
98 }
99
100 pub fn has_traits(&self) -> bool {
104 !self.triggers.is_empty()
105 || !self.replacements.is_empty()
106 || !self.spell_abilities.is_empty()
107 || !self.static_abilities.is_empty()
108 }
109
110 pub fn apply_spell_ability(&self, card: &mut crate::card::Card) {
114 for sa in &self.spell_abilities {
115 card.abilities.push(sa.clone());
116 }
117 }
118
119 pub fn apply_trigger(&self, card: &mut crate::card::Card) {
123 let mut next_id = card.triggers.len() as u32;
124 for trig_str in &self.triggers {
125 if let Some(trigger) = crate::trigger::trigger::parse_trigger(trig_str, &mut next_id) {
126 card.add_trigger(trigger);
127 }
128 }
129 }
130
131 pub fn apply_replacement_effect(&self, card: &mut crate::card::Card) {
135 for repl_str in &self.replacements {
136 if let Some(repl) =
137 crate::replacement::replacement_effect::parse_replacement_effect(repl_str)
138 {
139 card.add_replacement_effect(repl);
140 }
141 }
142 }
143
144 pub fn apply_static_ability(&self, card: &mut crate::card::Card) {
148 for sa_str in &self.static_abilities {
149 if let Some(sa) = crate::staticability::static_ability::parse_static_ability(sa_str) {
150 card.static_abilities.push(sa);
151 }
152 }
153 }
154
155 pub fn copy(&self) -> Self {
158 self.clone()
159 }
160
161 pub fn redundant(&self, other: &Self) -> bool {
164 if !self.data.keyword.is_multiple_redundant() {
165 return false;
166 }
167 self.data.original == other.data.original
168 }
169
170 pub fn has_s_var(&self, name: &str) -> bool {
173 self.svars.contains_key(name)
174 }
175
176 pub fn remove_s_var(&mut self, name: &str) {
179 self.svars.remove(name);
180 }
181}
182
183#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub enum Keyword {
187 Undefined,
188 Absorb,
189 Adapt,
190 Affinity,
191 Afflict,
192 Afterlife,
193 Aftermath,
194 Amplify,
195 Annihilator,
196 Ascend,
197 Assist,
198 AuraSwap,
199 Awaken,
200 Backup,
201 Banding,
202 BandsWith,
203 Bargain,
204 BattleCry,
205 Bestow,
206 Blitz,
207 Bloodthirst,
208 Bushido,
209 Buyback,
210 Cascade,
211 Casualty,
212 Champion,
213 Changeling,
214 ChooseABackground,
215 Cipher,
216 Companion,
217 Compleated,
218 Conspire,
219 Convoke,
220 Craft,
221 Crew,
222 CumulativeUpkeep,
223 Cycling,
224 Dash,
225 Daybound,
226 Deathtouch,
227 Decayed,
228 Defender,
229 Delve,
230 Demonstrate,
231 Dethrone,
232 Devour,
233 Devoid,
234 Disguise,
235 Disturb,
236 DoctorsCompanion,
237 DoubleAgenda,
238 DoubleStrike,
239 DoubleTeam,
240 Dredge,
241 Echo,
242 Embalm,
243 Emerge,
244 Enchant,
245 Encore,
246 Enlist,
247 Entwine,
248 Epic,
249 Equip,
250 Escape,
251 Escalate,
252 Eternalize,
253 Evoke,
254 Evolve,
255 Exalted,
256 Exploit,
257 Extort,
258 Fabricate,
259 Fading,
260 Fear,
261 Firebending,
262 FirstStrike,
263 Flanking,
264 Flash,
265 Flashback,
266 Flying,
267 ForMirrodin,
268 Foretell,
269 Fortify,
270 Freerunning,
271 Frenzy,
272 Fuse,
273 Gift,
274 Graft,
275 Gravestorm,
276 Harmonize,
277 Haste,
278 Haunt,
279 Hexproof,
280 Hideaway,
281 HiddenAgenda,
282 Horsemanship,
283 Impending,
284 Improvise,
285 Indestructible,
286 Infect,
287 Ingest,
288 Intimidate,
289 Kicker,
290 JobSelect,
291 JumpStart,
292 Landwalk,
293 LevelUp,
294 Lifelink,
295 LivingMetal,
296 LivingWeapon,
297 Madness,
298 Mayhem,
299 Melee,
300 Mentor,
301 Menace,
302 Megamorph,
303 Miracle,
304 Mobilize,
305 Monstrosity,
306 Modular,
307 MoreThanMeetsTheEye,
308 Morph,
309 Multikicker,
310 Mutate,
311 Myriad,
312 Nightbound,
313 Ninjutsu,
314 Outlast,
315 Offering,
316 Offspring,
317 Overload,
318 Partner,
319 PartnerWith,
320 Persist,
321 Phasing,
322 Plot,
323 Poisonous,
324 Protection,
325 Prototype,
326 Provoke,
327 Prowess,
328 Prowl,
329 Rampage,
330 Ravenous,
331 Reach,
332 ReadAhead,
333 Rebound,
334 Recover,
335 Reconfigure,
336 Reflect,
337 Reinforce,
338 Renown,
339 Replicate,
340 Retrace,
341 Riot,
342 Ripple,
343 Saddle,
344 Scavenge,
345 Shadow,
346 Shroud,
347 Skulk,
348 Sneak,
349 Soulbond,
350 Soulshift,
351 SpaceSculptor,
352 Specialize,
353 Spectacle,
354 Splice,
355 SplitSecond,
356 Spree,
357 Squad,
358 StartYourEngines,
359 StartingIntensity,
360 Station,
361 Storm,
362 Strive,
363 Sunburst,
364 Surge,
365 Suspend,
366 Tiered,
367 Toxic,
368 Training,
369 Trample,
370 Transfigure,
371 Transmute,
372 Tribute,
373 TypeCycling,
374 UmbraArmor,
375 Undaunted,
376 Undying,
377 Unearth,
378 Unleash,
379 Vanishing,
380 Vigilance,
381 Ward,
382 Warp,
383 WebSlinging,
384 Wither,
385 MayFlashCost,
386 MayFlashSac,
387}
388
389impl Keyword {
390 pub fn display_name(&self) -> &'static str {
392 match self {
393 Keyword::Undefined => "",
394 Keyword::Absorb => "Absorb",
395 Keyword::Adapt => "Adapt",
396 Keyword::Affinity => "Affinity",
397 Keyword::Afflict => "Afflict",
398 Keyword::Afterlife => "Afterlife",
399 Keyword::Aftermath => "Aftermath",
400 Keyword::Amplify => "Amplify",
401 Keyword::Annihilator => "Annihilator",
402 Keyword::Ascend => "Ascend",
403 Keyword::Assist => "Assist",
404 Keyword::AuraSwap => "Aura swap",
405 Keyword::Awaken => "Awaken",
406 Keyword::Backup => "Backup",
407 Keyword::Banding => "Banding",
408 Keyword::BandsWith => "Bands with other",
409 Keyword::Bargain => "Bargain",
410 Keyword::BattleCry => "Battle cry",
411 Keyword::Bestow => "Bestow",
412 Keyword::Blitz => "Blitz",
413 Keyword::Bloodthirst => "Bloodthirst",
414 Keyword::Bushido => "Bushido",
415 Keyword::Buyback => "Buyback",
416 Keyword::Cascade => "Cascade",
417 Keyword::Casualty => "Casualty",
418 Keyword::Champion => "Champion",
419 Keyword::Changeling => "Changeling",
420 Keyword::ChooseABackground => "Choose a Background",
421 Keyword::Cipher => "Cipher",
422 Keyword::Companion => "Companion",
423 Keyword::Compleated => "Compleated",
424 Keyword::Conspire => "Conspire",
425 Keyword::Convoke => "Convoke",
426 Keyword::Craft => "Craft",
427 Keyword::Crew => "Crew",
428 Keyword::CumulativeUpkeep => "Cumulative upkeep",
429 Keyword::Cycling => "Cycling",
430 Keyword::Dash => "Dash",
431 Keyword::Daybound => "Daybound",
432 Keyword::Deathtouch => "Deathtouch",
433 Keyword::Decayed => "Decayed",
434 Keyword::Defender => "Defender",
435 Keyword::Delve => "Delve",
436 Keyword::Demonstrate => "Demonstrate",
437 Keyword::Dethrone => "Dethrone",
438 Keyword::Devour => "Devour",
439 Keyword::Devoid => "Devoid",
440 Keyword::Disguise => "Disguise",
441 Keyword::Disturb => "Disturb",
442 Keyword::DoctorsCompanion => "Doctor's companion",
443 Keyword::DoubleAgenda => "Double agenda",
444 Keyword::DoubleStrike => "Double Strike",
445 Keyword::DoubleTeam => "Double team",
446 Keyword::Dredge => "Dredge",
447 Keyword::Echo => "Echo",
448 Keyword::Embalm => "Embalm",
449 Keyword::Emerge => "Emerge",
450 Keyword::Enchant => "Enchant",
451 Keyword::Encore => "Encore",
452 Keyword::Enlist => "Enlist",
453 Keyword::Entwine => "Entwine",
454 Keyword::Epic => "Epic",
455 Keyword::Equip => "Equip",
456 Keyword::Escape => "Escape",
457 Keyword::Escalate => "Escalate",
458 Keyword::Eternalize => "Eternalize",
459 Keyword::Evoke => "Evoke",
460 Keyword::Evolve => "Evolve",
461 Keyword::Exalted => "Exalted",
462 Keyword::Exploit => "Exploit",
463 Keyword::Extort => "Extort",
464 Keyword::Fabricate => "Fabricate",
465 Keyword::Fading => "Fading",
466 Keyword::Fear => "Fear",
467 Keyword::Firebending => "Firebending",
468 Keyword::FirstStrike => "First Strike",
469 Keyword::Flanking => "Flanking",
470 Keyword::Flash => "Flash",
471 Keyword::Flashback => "Flashback",
472 Keyword::Flying => "Flying",
473 Keyword::ForMirrodin => "For Mirrodin",
474 Keyword::Foretell => "Foretell",
475 Keyword::Fortify => "Fortify",
476 Keyword::Freerunning => "Freerunning",
477 Keyword::Frenzy => "Frenzy",
478 Keyword::Fuse => "Fuse",
479 Keyword::Gift => "Gift",
480 Keyword::Graft => "Graft",
481 Keyword::Gravestorm => "Gravestorm",
482 Keyword::Harmonize => "Harmonize",
483 Keyword::Haste => "Haste",
484 Keyword::Haunt => "Haunt",
485 Keyword::Hexproof => "Hexproof",
486 Keyword::Hideaway => "Hideaway",
487 Keyword::HiddenAgenda => "Hidden agenda",
488 Keyword::Horsemanship => "Horsemanship",
489 Keyword::Impending => "Impending",
490 Keyword::Improvise => "Improvise",
491 Keyword::Indestructible => "Indestructible",
492 Keyword::Infect => "Infect",
493 Keyword::Ingest => "Ingest",
494 Keyword::Intimidate => "Intimidate",
495 Keyword::Kicker => "Kicker",
496 Keyword::JobSelect => "Job select",
497 Keyword::JumpStart => "Jump-start",
498 Keyword::Landwalk => "Landwalk",
499 Keyword::LevelUp => "Level up",
500 Keyword::Lifelink => "Lifelink",
501 Keyword::LivingMetal => "Living metal",
502 Keyword::LivingWeapon => "Living Weapon",
503 Keyword::Madness => "Madness",
504 Keyword::Mayhem => "Mayhem",
505 Keyword::Melee => "Melee",
506 Keyword::Mentor => "Mentor",
507 Keyword::Menace => "Menace",
508 Keyword::Megamorph => "Megamorph",
509 Keyword::Miracle => "Miracle",
510 Keyword::Mobilize => "Mobilize",
511 Keyword::Monstrosity => "Monstrosity",
512 Keyword::Modular => "Modular",
513 Keyword::MoreThanMeetsTheEye => "More Than Meets the Eye",
514 Keyword::Morph => "Morph",
515 Keyword::Multikicker => "Multikicker",
516 Keyword::Mutate => "Mutate",
517 Keyword::Myriad => "Myriad",
518 Keyword::Nightbound => "Nightbound",
519 Keyword::Ninjutsu => "Ninjutsu",
520 Keyword::Outlast => "Outlast",
521 Keyword::Offering => "Offering",
522 Keyword::Offspring => "Offspring",
523 Keyword::Overload => "Overload",
524 Keyword::Partner => "Partner",
525 Keyword::PartnerWith => "Partner with",
526 Keyword::Persist => "Persist",
527 Keyword::Phasing => "Phasing",
528 Keyword::Plot => "Plot",
529 Keyword::Poisonous => "Poisonous",
530 Keyword::Protection => "Protection",
531 Keyword::Prototype => "Prototype",
532 Keyword::Provoke => "Provoke",
533 Keyword::Prowess => "Prowess",
534 Keyword::Prowl => "Prowl",
535 Keyword::Rampage => "Rampage",
536 Keyword::Ravenous => "Ravenous",
537 Keyword::Reach => "Reach",
538 Keyword::ReadAhead => "Read ahead",
539 Keyword::Rebound => "Rebound",
540 Keyword::Recover => "Recover",
541 Keyword::Reconfigure => "Reconfigure",
542 Keyword::Reflect => "Reflect",
543 Keyword::Reinforce => "Reinforce",
544 Keyword::Renown => "Renown",
545 Keyword::Replicate => "Replicate",
546 Keyword::Retrace => "Retrace",
547 Keyword::Riot => "Riot",
548 Keyword::Ripple => "Ripple",
549 Keyword::Saddle => "Saddle",
550 Keyword::Scavenge => "Scavenge",
551 Keyword::Shadow => "Shadow",
552 Keyword::Shroud => "Shroud",
553 Keyword::Skulk => "Skulk",
554 Keyword::Sneak => "Sneak",
555 Keyword::Soulbond => "Soulbond",
556 Keyword::Soulshift => "Soulshift",
557 Keyword::SpaceSculptor => "Space sculptor",
558 Keyword::Specialize => "Specialize",
559 Keyword::Spectacle => "Spectacle",
560 Keyword::Splice => "Splice",
561 Keyword::SplitSecond => "Split second",
562 Keyword::Spree => "Spree",
563 Keyword::Squad => "Squad",
564 Keyword::StartYourEngines => "Start your engines",
565 Keyword::StartingIntensity => "Starting intensity",
566 Keyword::Station => "Station",
567 Keyword::Storm => "Storm",
568 Keyword::Strive => "Strive",
569 Keyword::Sunburst => "Sunburst",
570 Keyword::Surge => "Surge",
571 Keyword::Suspend => "Suspend",
572 Keyword::Tiered => "Tiered",
573 Keyword::Toxic => "Toxic",
574 Keyword::Training => "Training",
575 Keyword::Trample => "Trample",
576 Keyword::Transfigure => "Transfigure",
577 Keyword::Transmute => "Transmute",
578 Keyword::Tribute => "Tribute",
579 Keyword::TypeCycling => "TypeCycling",
580 Keyword::UmbraArmor => "Umbra armor",
581 Keyword::Undaunted => "Undaunted",
582 Keyword::Undying => "Undying",
583 Keyword::Unearth => "Unearth",
584 Keyword::Unleash => "Unleash",
585 Keyword::Vanishing => "Vanishing",
586 Keyword::Vigilance => "Vigilance",
587 Keyword::Ward => "Ward",
588 Keyword::Warp => "Warp",
589 Keyword::WebSlinging => "Web-slinging",
590 Keyword::Wither => "Wither",
591 Keyword::MayFlashCost => "MayFlashCost",
592 Keyword::MayFlashSac => "MayFlashSac",
593 }
594 }
595
596 pub fn is_multiple_redundant(&self) -> bool {
598 matches!(
599 self,
600 Keyword::Ascend
601 | Keyword::Assist
602 | Keyword::Banding
603 | Keyword::Changeling
604 | Keyword::Cipher
605 | Keyword::Companion
606 | Keyword::Compleated
607 | Keyword::Convoke
608 | Keyword::Daybound
609 | Keyword::Deathtouch
610 | Keyword::Decayed
611 | Keyword::Defender
612 | Keyword::Delve
613 | Keyword::Devoid
614 | Keyword::DoubleStrike
615 | Keyword::Entwine
616 | Keyword::Epic
617 | Keyword::Fear
618 | Keyword::FirstStrike
619 | Keyword::Flash
620 | Keyword::Flying
621 | Keyword::Fuse
622 | Keyword::Gift
623 | Keyword::Haste
624 | Keyword::Hexproof
625 | Keyword::HiddenAgenda
626 | Keyword::Horsemanship
627 | Keyword::Improvise
628 | Keyword::Indestructible
629 | Keyword::Infect
630 | Keyword::Intimidate
631 | Keyword::Landwalk
632 | Keyword::Lifelink
633 | Keyword::LivingMetal
634 | Keyword::LivingWeapon
635 | Keyword::Mutate
636 | Keyword::Nightbound
637 | Keyword::Partner
638 | Keyword::Phasing
639 | Keyword::Protection
640 | Keyword::Reach
641 | Keyword::ReadAhead
642 | Keyword::Rebound
643 | Keyword::Shadow
644 | Keyword::Shroud
645 | Keyword::Skulk
646 | Keyword::Soulbond
647 | Keyword::SpaceSculptor
648 | Keyword::SplitSecond
649 | Keyword::Spree
650 | Keyword::StartYourEngines
651 | Keyword::StartingIntensity
652 | Keyword::Tiered
653 | Keyword::Trample
654 | Keyword::UmbraArmor
655 | Keyword::Vigilance
656 | Keyword::Wither
657 )
658 }
659
660 pub fn smart_value_of(value: &str) -> Keyword {
662 for kw in Self::all_variants() {
664 if kw.display_name().eq_ignore_ascii_case(value) {
665 return kw;
666 }
667 }
668 Keyword::Undefined
669 }
670
671 pub fn all_keywords() -> impl Iterator<Item = Keyword> {
673 Self::all_variants()
674 .into_iter()
675 .filter(|k| *k != Keyword::Undefined)
676 }
677
678 fn all_variants() -> Vec<Keyword> {
680 vec![
681 Keyword::Undefined,
682 Keyword::Absorb,
683 Keyword::Adapt,
684 Keyword::Affinity,
685 Keyword::Afflict,
686 Keyword::Afterlife,
687 Keyword::Aftermath,
688 Keyword::Amplify,
689 Keyword::Annihilator,
690 Keyword::Ascend,
691 Keyword::Assist,
692 Keyword::AuraSwap,
693 Keyword::Awaken,
694 Keyword::Backup,
695 Keyword::Banding,
696 Keyword::BandsWith,
697 Keyword::Bargain,
698 Keyword::BattleCry,
699 Keyword::Bestow,
700 Keyword::Blitz,
701 Keyword::Bloodthirst,
702 Keyword::Bushido,
703 Keyword::Buyback,
704 Keyword::Cascade,
705 Keyword::Casualty,
706 Keyword::Champion,
707 Keyword::Changeling,
708 Keyword::ChooseABackground,
709 Keyword::Cipher,
710 Keyword::Companion,
711 Keyword::Compleated,
712 Keyword::Conspire,
713 Keyword::Convoke,
714 Keyword::Craft,
715 Keyword::Crew,
716 Keyword::CumulativeUpkeep,
717 Keyword::Cycling,
718 Keyword::Dash,
719 Keyword::Daybound,
720 Keyword::Deathtouch,
721 Keyword::Decayed,
722 Keyword::Defender,
723 Keyword::Delve,
724 Keyword::Demonstrate,
725 Keyword::Dethrone,
726 Keyword::Devour,
727 Keyword::Devoid,
728 Keyword::Disguise,
729 Keyword::Disturb,
730 Keyword::DoctorsCompanion,
731 Keyword::DoubleAgenda,
732 Keyword::DoubleStrike,
733 Keyword::DoubleTeam,
734 Keyword::Dredge,
735 Keyword::Echo,
736 Keyword::Embalm,
737 Keyword::Emerge,
738 Keyword::Enchant,
739 Keyword::Encore,
740 Keyword::Enlist,
741 Keyword::Entwine,
742 Keyword::Epic,
743 Keyword::Equip,
744 Keyword::Escape,
745 Keyword::Escalate,
746 Keyword::Eternalize,
747 Keyword::Evoke,
748 Keyword::Evolve,
749 Keyword::Exalted,
750 Keyword::Exploit,
751 Keyword::Extort,
752 Keyword::Fabricate,
753 Keyword::Fading,
754 Keyword::Fear,
755 Keyword::Firebending,
756 Keyword::FirstStrike,
757 Keyword::Flanking,
758 Keyword::Flash,
759 Keyword::Flashback,
760 Keyword::Flying,
761 Keyword::ForMirrodin,
762 Keyword::Foretell,
763 Keyword::Fortify,
764 Keyword::Freerunning,
765 Keyword::Frenzy,
766 Keyword::Fuse,
767 Keyword::Gift,
768 Keyword::Graft,
769 Keyword::Gravestorm,
770 Keyword::Harmonize,
771 Keyword::Haste,
772 Keyword::Haunt,
773 Keyword::Hexproof,
774 Keyword::Hideaway,
775 Keyword::HiddenAgenda,
776 Keyword::Horsemanship,
777 Keyword::Impending,
778 Keyword::Improvise,
779 Keyword::Indestructible,
780 Keyword::Infect,
781 Keyword::Ingest,
782 Keyword::Intimidate,
783 Keyword::Kicker,
784 Keyword::JobSelect,
785 Keyword::JumpStart,
786 Keyword::Landwalk,
787 Keyword::LevelUp,
788 Keyword::Lifelink,
789 Keyword::LivingMetal,
790 Keyword::LivingWeapon,
791 Keyword::Madness,
792 Keyword::Mayhem,
793 Keyword::Melee,
794 Keyword::Mentor,
795 Keyword::Menace,
796 Keyword::Megamorph,
797 Keyword::Miracle,
798 Keyword::Mobilize,
799 Keyword::Monstrosity,
800 Keyword::Modular,
801 Keyword::MoreThanMeetsTheEye,
802 Keyword::Morph,
803 Keyword::Multikicker,
804 Keyword::Mutate,
805 Keyword::Myriad,
806 Keyword::Nightbound,
807 Keyword::Ninjutsu,
808 Keyword::Outlast,
809 Keyword::Offering,
810 Keyword::Offspring,
811 Keyword::Overload,
812 Keyword::Partner,
813 Keyword::PartnerWith,
814 Keyword::Persist,
815 Keyword::Phasing,
816 Keyword::Plot,
817 Keyword::Poisonous,
818 Keyword::Protection,
819 Keyword::Prototype,
820 Keyword::Provoke,
821 Keyword::Prowess,
822 Keyword::Prowl,
823 Keyword::Rampage,
824 Keyword::Ravenous,
825 Keyword::Reach,
826 Keyword::ReadAhead,
827 Keyword::Rebound,
828 Keyword::Recover,
829 Keyword::Reconfigure,
830 Keyword::Reflect,
831 Keyword::Reinforce,
832 Keyword::Renown,
833 Keyword::Replicate,
834 Keyword::Retrace,
835 Keyword::Riot,
836 Keyword::Ripple,
837 Keyword::Saddle,
838 Keyword::Scavenge,
839 Keyword::Shadow,
840 Keyword::Shroud,
841 Keyword::Skulk,
842 Keyword::Sneak,
843 Keyword::Soulbond,
844 Keyword::Soulshift,
845 Keyword::SpaceSculptor,
846 Keyword::Specialize,
847 Keyword::Spectacle,
848 Keyword::Splice,
849 Keyword::SplitSecond,
850 Keyword::Spree,
851 Keyword::Squad,
852 Keyword::StartYourEngines,
853 Keyword::StartingIntensity,
854 Keyword::Station,
855 Keyword::Storm,
856 Keyword::Strive,
857 Keyword::Sunburst,
858 Keyword::Surge,
859 Keyword::Suspend,
860 Keyword::Tiered,
861 Keyword::Toxic,
862 Keyword::Training,
863 Keyword::Trample,
864 Keyword::Transfigure,
865 Keyword::Transmute,
866 Keyword::Tribute,
867 Keyword::TypeCycling,
868 Keyword::UmbraArmor,
869 Keyword::Undaunted,
870 Keyword::Undying,
871 Keyword::Unearth,
872 Keyword::Unleash,
873 Keyword::Vanishing,
874 Keyword::Vigilance,
875 Keyword::Ward,
876 Keyword::Warp,
877 Keyword::WebSlinging,
878 Keyword::Wither,
879 Keyword::MayFlashCost,
880 Keyword::MayFlashSac,
881 ]
882 }
883}
884
885impl fmt::Display for Keyword {
886 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
887 write!(f, "{}", self.display_name())
888 }
889}