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 let enum_ = match ty.as_adt() {
25 Some(hir::Adt::Enum(it)) => it,
26 _ => return None,
27 };
28 TryEnum::ALL.iter().find_map(|&var| {
29 if enum_.name(sema.db).as_str() == var.type_name() {
30 return Some(var);
31 }
32 None
33 })
34 }
35
36 pub fn happy_case(self) -> &'static str {
37 match self {
38 TryEnum::Result => "Ok",
39 TryEnum::Option => "Some",
40 }
41 }
42
43 pub fn sad_pattern(self) -> ast::Pat {
44 match self {
45 TryEnum::Result => make::tuple_struct_pat(
46 make::ext::ident_path("Err"),
47 iter::once(make::wildcard_pat().into()),
48 )
49 .into(),
50 TryEnum::Option => make::ext::simple_ident_pat(make::name("None")).into(),
51 }
52 }
53
54 pub fn happy_pattern(self, pat: Pat) -> ast::Pat {
55 match self {
56 TryEnum::Result => {
57 make::tuple_struct_pat(make::ext::ident_path("Ok"), iter::once(pat)).into()
58 }
59 TryEnum::Option => {
60 make::tuple_struct_pat(make::ext::ident_path("Some"), iter::once(pat)).into()
61 }
62 }
63 }
64
65 pub fn happy_pattern_wildcard(self) -> ast::Pat {
66 match self {
67 TryEnum::Result => make::tuple_struct_pat(
68 make::ext::ident_path("Ok"),
69 iter::once(make::wildcard_pat().into()),
70 )
71 .into(),
72 TryEnum::Option => make::tuple_struct_pat(
73 make::ext::ident_path("Some"),
74 iter::once(make::wildcard_pat().into()),
75 )
76 .into(),
77 }
78 }
79
80 fn type_name(self) -> &'static str {
81 match self {
82 TryEnum::Result => "Result",
83 TryEnum::Option => "Option",
84 }
85 }
86}