You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

keywords.rs 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. // Copyright (C) 2019 Inderjit Gill
  2. // This program is free software: you can redistribute it and/or modify
  3. // it under the terms of the GNU General Public License as published by
  4. // the Free Software Foundation, either version 3 of the License, or
  5. // (at your option) any later version.
  6. // This program is distributed in the hope that it will be useful,
  7. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. // GNU General Public License for more details.
  10. // You should have received a copy of the GNU General Public License
  11. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  12. use std::collections::HashMap;
  13. use strum::IntoEnumIterator;
  14. use strum_macros::{Display, EnumIter, EnumString};
  15. use crate::iname::Iname;
  16. use crate::packable::{Mule, Packable};
  17. use crate::result::Result;
  18. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, EnumString, Display, EnumIter)]
  19. pub enum Keyword {
  20. #[strum(serialize = "UnreachableKeywordStart")]
  21. KeywordStart = 127,
  22. #[strum(serialize = "false")]
  23. False,
  24. #[strum(serialize = "true")]
  25. True,
  26. // mathematical special forms
  27. //
  28. #[strum(serialize = "+")]
  29. Plus,
  30. #[strum(serialize = "-")]
  31. Minus,
  32. #[strum(serialize = "*")]
  33. Mult,
  34. #[strum(serialize = "/")]
  35. Divide,
  36. #[strum(serialize = "=")]
  37. Equal,
  38. #[strum(serialize = ">")]
  39. Gt,
  40. #[strum(serialize = "<")]
  41. Lt,
  42. // built-in keywords/special-forms
  43. //
  44. #[strum(serialize = "++")]
  45. VectorAppend,
  46. #[strum(serialize = "sqrt")]
  47. Sqrt,
  48. #[strum(serialize = "mod")]
  49. Mod,
  50. #[strum(serialize = "and")]
  51. And,
  52. #[strum(serialize = "or")]
  53. Or,
  54. #[strum(serialize = "not")]
  55. Not,
  56. #[strum(serialize = "define")]
  57. Define,
  58. #[strum(serialize = "fn")]
  59. Fn,
  60. #[strum(serialize = "if")]
  61. If,
  62. #[strum(serialize = "each")]
  63. Each,
  64. #[strum(serialize = "loop")]
  65. Loop,
  66. #[strum(serialize = "fence")]
  67. Fence,
  68. #[strum(serialize = "on-matrix-stack")]
  69. OnMatrixStack,
  70. #[strum(serialize = "setq")]
  71. Setq,
  72. #[strum(serialize = "address-of")]
  73. AddressOf,
  74. #[strum(serialize = "fn-call")]
  75. FnCall,
  76. #[strum(serialize = "quote")]
  77. Quote,
  78. // pre-defined globals
  79. //
  80. #[strum(serialize = "#vars")]
  81. HashVars,
  82. #[strum(serialize = "canvas/width")]
  83. CanvasWidth,
  84. #[strum(serialize = "canvas/height")]
  85. CanvasHeight,
  86. #[strum(serialize = "math/PI")]
  87. MathPi,
  88. #[strum(serialize = "math/TAU")]
  89. MathTau,
  90. // colour formats
  91. //
  92. #[strum(serialize = "RGB")]
  93. Rgb,
  94. #[strum(serialize = "HSL")]
  95. Hsl,
  96. #[strum(serialize = "HSLuv")]
  97. Hsluv,
  98. #[strum(serialize = "LAB")]
  99. Lab,
  100. #[strum(serialize = "HSV")]
  101. Hsv,
  102. // pre-defined colours
  103. //
  104. #[strum(serialize = "white")]
  105. White,
  106. #[strum(serialize = "black")]
  107. Black,
  108. #[strum(serialize = "red")]
  109. Red,
  110. #[strum(serialize = "green")]
  111. Green,
  112. #[strum(serialize = "blue")]
  113. Blue,
  114. #[strum(serialize = "yellow")]
  115. Yellow,
  116. #[strum(serialize = "magenta")]
  117. Magenta,
  118. #[strum(serialize = "cyan")]
  119. Cyan,
  120. // procedural colours
  121. //
  122. #[strum(serialize = "chrome")]
  123. Chrome,
  124. #[strum(serialize = "hotline-miami")]
  125. HotlineMiami,
  126. #[strum(serialize = "knight-rider")]
  127. KnightRider,
  128. #[strum(serialize = "mars")]
  129. Mars,
  130. #[strum(serialize = "rainbow")]
  131. Rainbow,
  132. #[strum(serialize = "robocop")]
  133. Robocop,
  134. #[strum(serialize = "transformers")]
  135. Transformers,
  136. #[strum(serialize = "col/procedural-fn-presets")] // globally mapped in preamble
  137. ColProceduralFnPresets,
  138. // brush types
  139. //
  140. #[strum(serialize = "brush/flat")]
  141. BrushFlat,
  142. #[strum(serialize = "brush/a")]
  143. BrushA,
  144. #[strum(serialize = "brush/b")]
  145. BrushB,
  146. #[strum(serialize = "brush/c")]
  147. BrushC,
  148. #[strum(serialize = "brush/d")]
  149. BrushD,
  150. #[strum(serialize = "brush/e")]
  151. BrushE,
  152. #[strum(serialize = "brush/f")]
  153. BrushF,
  154. #[strum(serialize = "brush/g")]
  155. BrushG,
  156. #[strum(serialize = "brush/*")] // globally mapped in preamble
  157. BrushAll,
  158. // interpolation
  159. //
  160. #[strum(serialize = "linear")]
  161. Linear,
  162. #[strum(serialize = "ease/quick")]
  163. EaseQuick,
  164. #[strum(serialize = "ease/slow-in")]
  165. EaseSlowIn,
  166. #[strum(serialize = "ease/slow-in-out")]
  167. EaseSlowInOut,
  168. #[strum(serialize = "ease/quadratic-in")]
  169. EaseQuadraticIn,
  170. #[strum(serialize = "ease/quadratic-out")]
  171. EaseQuadraticOut,
  172. #[strum(serialize = "ease/quadratic-in-out")]
  173. EaseQuadraticInOut,
  174. #[strum(serialize = "ease/cubic-in")]
  175. EaseCubicIn,
  176. #[strum(serialize = "ease/cubic-out")]
  177. EaseCubicOut,
  178. #[strum(serialize = "ease/cubic-in-out")]
  179. EaseCubicInOut,
  180. #[strum(serialize = "ease/quartic-in")]
  181. EaseQuarticIn,
  182. #[strum(serialize = "ease/quartic-out")]
  183. EaseQuarticOut,
  184. #[strum(serialize = "ease/quartic-in-out")]
  185. EaseQuarticInOut,
  186. #[strum(serialize = "ease/quintic-in")]
  187. EaseQuinticIn,
  188. #[strum(serialize = "ease/quintic-out")]
  189. EaseQuinticOut,
  190. #[strum(serialize = "ease/quintic-in-out")]
  191. EaseQuinticInOut,
  192. #[strum(serialize = "ease/sin-in")]
  193. EaseSinIn,
  194. #[strum(serialize = "ease/sin-out")]
  195. EaseSinOut,
  196. #[strum(serialize = "ease/sin-in-out")]
  197. EaseSinInOut,
  198. #[strum(serialize = "ease/circular-in")]
  199. EaseCircularIn,
  200. #[strum(serialize = "ease/circular-out")]
  201. EaseCircularOut,
  202. #[strum(serialize = "ease/circular-in-out")]
  203. EaseCircularInOut,
  204. #[strum(serialize = "ease/exponential-in")]
  205. EaseExponentialIn,
  206. #[strum(serialize = "ease/exponential-out")]
  207. EaseExponentialOut,
  208. #[strum(serialize = "ease/exponential-in-out")]
  209. EaseExponentialInOut,
  210. #[strum(serialize = "ease/elastic-in")]
  211. EaseElasticIn,
  212. #[strum(serialize = "ease/elastic-out")]
  213. EaseElasticOut,
  214. #[strum(serialize = "ease/elastic-in-out")]
  215. EaseElasticInOut,
  216. #[strum(serialize = "ease/back-in")]
  217. EaseBackIn,
  218. #[strum(serialize = "ease/back-out")]
  219. EaseBackOut,
  220. #[strum(serialize = "ease/back-in-out")]
  221. EaseBackInOut,
  222. #[strum(serialize = "ease/bounce-in")]
  223. EaseBounceIn,
  224. #[strum(serialize = "ease/bounce-out")]
  225. EaseBounceOut,
  226. #[strum(serialize = "ease/bounce-in-out")]
  227. EaseBounceInOut,
  228. #[strum(serialize = "ease/*")] // globally mapped in preamble
  229. EaseAll,
  230. // common parameter labels
  231. //
  232. #[strum(serialize = "a")]
  233. A,
  234. #[strum(serialize = "b")]
  235. B,
  236. #[strum(serialize = "c")]
  237. C,
  238. #[strum(serialize = "d")]
  239. D,
  240. #[strum(serialize = "g")]
  241. G,
  242. #[strum(serialize = "h")]
  243. H,
  244. #[strum(serialize = "l")]
  245. L,
  246. #[strum(serialize = "n")]
  247. N,
  248. #[strum(serialize = "r")]
  249. R,
  250. #[strum(serialize = "s")]
  251. S,
  252. #[strum(serialize = "t")]
  253. T,
  254. #[strum(serialize = "v")]
  255. V,
  256. #[strum(serialize = "x")]
  257. X,
  258. #[strum(serialize = "y")]
  259. Y,
  260. #[strum(serialize = "z")]
  261. Z,
  262. #[strum(serialize = "alpha")]
  263. Alpha,
  264. #[strum(serialize = "amplitude")]
  265. Amplitude,
  266. #[strum(serialize = "angle")]
  267. Angle,
  268. #[strum(serialize = "angle-end")]
  269. AngleEnd,
  270. #[strum(serialize = "angle-start")]
  271. AngleStart,
  272. #[strum(serialize = "brush")]
  273. Brush,
  274. #[strum(serialize = "brush-subtype")]
  275. BrushSubtype,
  276. #[strum(serialize = "by")]
  277. By,
  278. #[strum(serialize = "clamping")]
  279. Clamping,
  280. #[strum(serialize = "colour")]
  281. Colour,
  282. #[strum(serialize = "colour-volatility")]
  283. ColourVolatility,
  284. #[strum(serialize = "colours")]
  285. Colours,
  286. #[strum(serialize = "coords")]
  287. Coords,
  288. #[strum(serialize = "copies")]
  289. Copies,
  290. #[strum(serialize = "copy")]
  291. Copy,
  292. #[strum(serialize = "direction")]
  293. Direction,
  294. #[strum(serialize = "distance")]
  295. Distance,
  296. #[strum(serialize = "format")]
  297. Format,
  298. #[strum(serialize = "frequency")]
  299. Frequency,
  300. #[strum(serialize = "from")]
  301. From,
  302. #[strum(serialize = "from-colour")]
  303. FromColour,
  304. #[strum(serialize = "height")]
  305. Height,
  306. #[strum(serialize = "inc")]
  307. Inc,
  308. #[strum(serialize = "inner-height")]
  309. InnerHeight,
  310. #[strum(serialize = "inner-width")]
  311. InnerWidth,
  312. #[strum(serialize = "iterations")]
  313. Iterations,
  314. #[strum(serialize = "linear-colour-space")]
  315. LinearColourSpace,
  316. #[strum(serialize = "line-width")]
  317. LineWidth,
  318. #[strum(serialize = "line-width-end")]
  319. LineWidthEnd,
  320. #[strum(serialize = "line-width-mapping")]
  321. LineWidthMapping,
  322. #[strum(serialize = "line-width-start")]
  323. LineWidthStart,
  324. #[strum(serialize = "mapping")]
  325. Mapping,
  326. #[strum(serialize = "max")]
  327. Max,
  328. #[strum(serialize = "min")]
  329. Min,
  330. #[strum(serialize = "num")]
  331. Num,
  332. #[strum(serialize = "overlap")]
  333. Overlap,
  334. #[strum(serialize = "point")]
  335. Point,
  336. #[strum(serialize = "position")]
  337. Position,
  338. #[strum(serialize = "preset")]
  339. Preset,
  340. #[strum(serialize = "radius")]
  341. Radius,
  342. #[strum(serialize = "scalar")]
  343. Scalar,
  344. #[strum(serialize = "scalars")]
  345. Scalars,
  346. #[strum(serialize = "seed")]
  347. Seed,
  348. #[strum(serialize = "shuffle-seed")]
  349. ShuffleSeed,
  350. #[strum(serialize = "steps")]
  351. Steps,
  352. #[strum(serialize = "stroke-line-width-end")]
  353. StrokeLineWidthEnd,
  354. #[strum(serialize = "stroke-line-width-start")]
  355. StrokeLineWidthStart,
  356. #[strum(serialize = "stroke-noise")]
  357. StrokeNoise,
  358. #[strum(serialize = "stroke-tessellation")]
  359. StrokeTessellation,
  360. #[strum(serialize = "t-end")]
  361. TEnd,
  362. #[strum(serialize = "t-start")]
  363. TStart,
  364. #[strum(serialize = "tessellation")]
  365. Tessellation,
  366. #[strum(serialize = "transform-position")]
  367. TransformPosition,
  368. #[strum(serialize = "to")]
  369. To,
  370. #[strum(serialize = "to-colour")]
  371. ToColour,
  372. #[strum(serialize = "upto")]
  373. Upto,
  374. #[strum(serialize = "value")]
  375. Value,
  376. #[strum(serialize = "vec1")]
  377. Vec1,
  378. #[strum(serialize = "vec2")]
  379. Vec2,
  380. #[strum(serialize = "vector")]
  381. Vector,
  382. #[strum(serialize = "volatility")]
  383. Volatility,
  384. #[strum(serialize = "width")]
  385. Width,
  386. #[strum(serialize = "worldspace")]
  387. WorldSpace,
  388. #[strum(serialize = "UnreachableKeywordEnd")]
  389. KeywordEnd,
  390. }
  391. impl Packable for Keyword {
  392. fn pack(&self, cursor: &mut String) -> Result<()> {
  393. Mule::pack_label(cursor, &self.to_string());
  394. Ok(())
  395. }
  396. fn unpack(cursor: &str) -> Result<(Self, &str)> {
  397. let ns = Mule::next_space(cursor);
  398. let sub = &cursor[0..ns];
  399. let res = sub.parse::<Keyword>()?;
  400. Ok((res, &cursor[ns..]))
  401. }
  402. }
  403. pub fn name_to_keyword_hash() -> HashMap<Iname, Keyword> {
  404. let mut hm: HashMap<Iname, Keyword> = HashMap::new();
  405. for kw in Keyword::iter() {
  406. hm.insert(Iname::from(kw), kw);
  407. }
  408. hm
  409. }
  410. #[cfg(test)]
  411. mod tests {
  412. use super::*;
  413. #[test]
  414. fn test_keyword_enums() {
  415. assert_eq!(Keyword::False as i32, 128);
  416. assert_eq!(Keyword::True as i32, 129);
  417. assert_eq!(Keyword::Width as i32, 300);
  418. }
  419. #[test]
  420. fn test_keyword_pack() {
  421. let mut res: String = "".to_string();
  422. Keyword::Volatility.pack(&mut res).unwrap();
  423. assert_eq!("volatility", res);
  424. }
  425. #[test]
  426. fn test_keyword_unpack() {
  427. let (res, _rem) = Keyword::unpack("volatility").unwrap();
  428. assert_eq!(res, Keyword::Volatility);
  429. }
  430. }