1use nifty_runtime::{DownloadCommand, DownloadField};
5
6use crate::elements::{BoundType, Param, ParamKind, named, positional, required};
7
8#[derive(Debug)]
10pub struct Function {
11 pub name: &'static str,
12 pub kind: FunctionKind,
13 pub params: &'static [Param],
14 pub value: Option<BoundType>,
16 pub summary: &'static str,
17}
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
21pub enum FunctionKind {
22 Download,
23 PickFile,
24 PickFiles,
25 PickFolder,
26 PickSavePath,
27 OpenWindow,
28 CloseWindow,
29 FormatBytes,
30 DownloadCommand(DownloadCommand),
32}
33
34pub const DOWNLOAD: &str = "download";
36
37pub const CONNECTIONS: &str = "connections";
39pub const DEFAULT_CONNECTIONS: i64 = 1;
41pub const HEADERS: &str = "headers";
43pub const RETRIES: &str = "retries";
46pub const DEFAULT_RETRIES: i64 = 0;
48
49pub const FORMAT_BYTES: &str = "format_bytes";
51
52pub const OPEN_WINDOW: &str = "open_window";
54
55pub const TITLE: &str = "title";
58pub const TYPES: &str = "types";
59pub const FROM: &str = "from";
60pub const NAME: &str = "name";
62
63const TITLE_PARAM: Param = named(TITLE, ParamKind::Text);
64const TYPES_PARAM: Param = named(TYPES, ParamKind::TextList);
65const FROM_PARAM: Param = named(FROM, ParamKind::Text);
66const WINDOW_PARAM: Param = positional("window", ParamKind::Window);
67const DOWNLOAD_ID_PARAM: Param = positional("id", ParamKind::Text);
68
69pub(crate) const fn download_bound_type(field: DownloadField) -> BoundType {
71 if field.is_text() {
72 BoundType::String
73 } else {
74 BoundType::Int
75 }
76}
77
78const fn download_command(command: DownloadCommand, summary: &'static str) -> Function {
81 Function {
82 name: command.function(),
83 kind: FunctionKind::DownloadCommand(command),
84 params: &[DOWNLOAD_ID_PARAM],
85 value: None,
86 summary,
87 }
88}
89
90const fn download_binding(field: DownloadField) -> Param {
92 let kind = ParamKind::Binding(download_bound_type(field));
93 if field.is_required() {
94 required(field.name(), kind)
95 } else {
96 named(field.name(), kind)
97 }
98}
99
100pub const FUNCTIONS: &[Function] = &[
101 Function {
102 name: DOWNLOAD,
103 kind: FunctionKind::Download,
104 params: &[
105 positional("url", ParamKind::Text),
106 required("to", ParamKind::Text),
107 download_binding(DownloadField::Progress),
108 download_binding(DownloadField::Status),
109 download_binding(DownloadField::Received),
110 download_binding(DownloadField::Total),
111 download_binding(DownloadField::Speed),
112 download_binding(DownloadField::Id),
113 named(NAME, ParamKind::Text),
114 named(CONNECTIONS, ParamKind::Number),
115 named(HEADERS, ParamKind::TextList),
116 named(RETRIES, ParamKind::Number),
117 ],
118 value: None,
119 summary: "Saves the file at a web address into a folder, in the background.",
120 },
121 Function {
122 name: "pick_file",
123 kind: FunctionKind::PickFile,
124 params: &[
125 positional("path", ParamKind::Binding(BoundType::String)),
126 TITLE_PARAM,
127 TYPES_PARAM,
128 FROM_PARAM,
129 ],
130 value: None,
131 summary: "Asks the user to choose a file, and writes its path into the bound state.",
132 },
133 Function {
134 name: "pick_files",
135 kind: FunctionKind::PickFiles,
136 params: &[
137 positional("paths", ParamKind::Binding(BoundType::Strings)),
138 TITLE_PARAM,
139 TYPES_PARAM,
140 FROM_PARAM,
141 ],
142 value: None,
143 summary: "Asks the user to choose files, and writes their paths into the bound list.",
144 },
145 Function {
146 name: "pick_folder",
147 kind: FunctionKind::PickFolder,
148 params: &[
149 positional("folder", ParamKind::Binding(BoundType::String)),
150 TITLE_PARAM,
151 FROM_PARAM,
152 ],
153 value: None,
154 summary: "Asks the user to choose a folder, and writes its path into the bound state.",
155 },
156 Function {
157 name: "pick_save_path",
158 kind: FunctionKind::PickSavePath,
159 params: &[
160 positional("path", ParamKind::Binding(BoundType::String)),
161 TITLE_PARAM,
162 TYPES_PARAM,
163 named(NAME, ParamKind::Text),
164 FROM_PARAM,
165 ],
166 value: None,
167 summary: "Asks the user where to save a file, and writes that path into the bound state.",
168 },
169 Function {
170 name: OPEN_WINDOW,
171 kind: FunctionKind::OpenWindow,
172 params: &[WINDOW_PARAM],
173 value: None,
174 summary: "Opens the window with this name, or brings it to the front if it's open.",
175 },
176 Function {
177 name: "close_window",
178 kind: FunctionKind::CloseWindow,
179 params: &[WINDOW_PARAM],
180 value: None,
181 summary: "Closes the window with this name, if it's open.",
182 },
183 Function {
184 name: FORMAT_BYTES,
185 kind: FunctionKind::FormatBytes,
186 params: &[positional("bytes", ParamKind::Number)],
187 value: Some(BoundType::String),
188 summary: "A size in bytes as text, such as `1.5 MB`.",
189 },
190 download_command(
191 DownloadCommand::Cancel,
192 "Stops the download with this id for good, removing what it saved so far.",
193 ),
194 download_command(
195 DownloadCommand::Pause,
196 "Pauses the download with this id, keeping what it saved so far.",
197 ),
198 download_command(
199 DownloadCommand::Resume,
200 "Carries on with the paused download with this id from where it stopped.",
201 ),
202];
203
204#[must_use]
206pub fn function(name: &str) -> Option<&'static Function> {
207 FUNCTIONS.iter().find(|function| function.name == name)
208}