1use std::iter;
6
7use hir::Semantics;
8use syntax::ast::{self, Pat, make};
9
10use crate::RootDatabase;
11
12#[derive(Clone, Copy, Debug)]
14pub enum TryEnum {
15 Result,
16 Option,
17}
18
19impl TryEnum {
20 const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result];
21
22 pub fn from_ty(sema: &Semantics<'_, RootDatabase>, ty: &hir::Type<'_>) -> Option<TryEnum> {
24 Self::from_ty_without_strip(sema, &ty.strip_references())
25 }
26
27 pub fn from_ty_without_strip(
29 sema: &Semantics<'_, RootDatabase>,
30 ty: &hir::Type<'_>,
31 ) -> Option<TryEnum> {
32 let enum_ = match ty.as_adt() {
33 Some(hir::Adt::Enum(it)) => it,
34 _ => return None,
35 };
36 TryEnum::ALL.iter().find_map(|&var| {
37 if enum_.name(sema.db).as_str() == var.type_name() {
38 return Some(var);
39 }
40 None
41 })
42 }
43
44 pub fn happy_case(self) -> &'static str {
45 match self {
46 TryEnum::Result => "Ok",
47 TryEnum::Option => "Some",
48 }
49 }
50
51 pub fn sad_pattern(self) -> ast::Pat {
52 match self {
53 TryEnum::Result => make::tuple_struct_pat(
54 make::ext::ident_path("Err"),
55 iter::once(make::wildcard_pat().into()),
56 )
57 .into(),
58 TryEnum::Option => make::ext::simple_ident_pat(make::name("None")).into(),
59 }
60 }
61
62 pub fn happy_pattern(self, pat: Pat) -> ast::Pat {
63 match self {
64 TryEnum::Result => {
65 make::tuple_struct_pat(make::ext::ident_path("Ok"), iter::once(pat)).into()
66 }
67 TryEnum::Option => {
68 make::tuple_struct_pat(make::ext::ident_path("Some"), iter::once(pat)).into()
69 }
70 }
71 }
72
73 pub fn happy_pattern_wildcard(self) -> ast::Pat {
74 match self {
75 TryEnum::Result => make::tuple_struct_pat(
76 make::ext::ident_path("Ok"),
77 iter::once(make::wildcard_pat().into()),
78 )
79 .into(),
80 TryEnum::Option => make::tuple_struct_pat(
81 make::ext::ident_path("Some"),
82 iter::once(make::wildcard_pat().into()),
83 )
84 .into(),
85 }
86 }
87
88 fn type_name(self) -> &'static str {
89 match self {
90 TryEnum::Result => "Result",
91 TryEnum::Option => "Option",
92 }
93 }
94}