aboutsummaryrefslogtreecommitdiff
path: root/examples/example-enum-tag/src/main.rs
blob: ad9db8208f97fe73fb8d3e403fd3e57108634a75 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Example Enum Tag
//!
//! > This example demonstrates how to use the `EnumTag` derive macro to tag enum variants with metadata,
//! > which can be used for autocompletion and parsing
//!
//! Run:
//! ```bash
//! cargo run --manifest-path examples/example-enum-tag/Cargo.toml --quiet -- lang-select OCaml
//! cargo run --manifest-path examples/example-enum-tag/Cargo.toml --quiet -- lang-select
//! ```
//!
//! Output:
//! ```plaintext
//! Selected: OCaml (A representative functional programming language with strong type inference)
//! Selected: Rust (A systems programming language focused on performance, safety, and concurrency)
//! ```

use mingling::{
    macros::suggest_enum, parser::PickableEnum, prelude::*, EnumTag, Groupped, ShellContext,
    Suggest,
};

// Define the enum and derive the EnumTag trait
//                        ________ adds metadata to the enum, enabling it to:
//                       /         1. Be used by the `suggest_enum!(Enum)` macro under the `comp` feature for autocompletion
//                       vvvvvvv   2. Implement the `PickableEnum` trait
#[derive(Debug, Default, EnumTag, Groupped)]
pub enum ProgrammingLanguages {
    #[enum_desc("An efficient and flexible compiled language widely used for system programming")]
    C,

    #[enum_rename("C++")]
    #[enum_desc("A high-performance language extending C with object-oriented features")]
    CPlusPlus,

    #[enum_rename("C#")]
    #[enum_desc("Microsoft's object-oriented programming language running on the .NET platform")]
    Csharp,

    #[enum_desc(
        "A cross-platform object-oriented language widely used for enterprise application development"
    )]
    Java,

    #[enum_desc(
        "A dynamic scripting language for web development, supporting prototype chain inheritance"
    )]
    JavaScript,

    #[enum_desc("A modern statically typed language running on the JVM, concise and safe")]
    Kotlin,

    #[enum_desc("A representative functional programming language with strong type inference")]
    OCaml,

    #[enum_desc("A general-purpose programming language with clean syntax, known for readability")]
    Python,

    #[enum_desc(
        "An object-oriented scripting language, famous for its concise and elegant syntax"
    )]
    Ruby,

    #[default]
    #[enum_desc("A systems programming language focused on performance, safety, and concurrency")]
    Rust,
}

// --------- IMPORTANT ---------
// Implement the PickableEnum trait for ProgrammingLanguages,
// so that `Picker` can parse this enum
impl PickableEnum for ProgrammingLanguages {}
// --------- IMPORTANT ---------

dispatcher!("lang-select", CMDLanguageSelection => EntryLanguageSelection);

#[chain]
fn handle_language_selection(args: EntryLanguageSelection) -> Next {
    // You can use Picker to directly parse ProgrammingLanguages
    let lang: ProgrammingLanguages = args.pick(()).unpack();
    lang
}

/// Renders the selected programming language with its name and description.
#[renderer]
fn render_programming_language(lang: ProgrammingLanguages) {
    // You can use `enum_info()` to get the name and description of the current enum
    let (name, desc) = lang.enum_info();
    r_println!("Selected: {} ({})", name, desc)
}

#[completion(EntryLanguageSelection)]
fn complete_language_selection(_: &ShellContext) -> Suggest {
    // Use `suggest_enum!` directly to generate enum suggestions
    suggest_enum!(ProgrammingLanguages)
}

gen_program!();

fn main() {
    let mut program = ThisProgram::new();
    program.with_dispatcher(CMDCompletion);
    program.with_dispatcher(CMDLanguageSelection);
    program.exec_and_exit();
}