ide_db/
ty_filter.rs

1//! This module contains structures for filtering the expected types.
2//! Use case for structures in this module is, for example, situation when you need to process
3//! only certain `Enum`s.
4
5use std::iter;
6
7use hir::Semantics;
8use syntax::ast::{self, Pat, make};
9
10use crate::RootDatabase;
11
12/// Enum types that implement `std::ops::Try` trait.
13#[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    /// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`.
23    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}