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 `ty.strip_references()` is an enum that implements `std::ops::Try`.
23    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    /// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`.
28    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}