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.

157 lines
3.1 KiB

  1. use crate::error::ShellError;
  2. use crate::prompt::PromptStyle;
  3. use once_cell::unsync::Lazy;
  4. mod blahaj;
  5. mod cd;
  6. mod change_prompt;
  7. mod exit;
  8. mod fetch;
  9. mod help;
  10. mod logout;
  11. mod ls;
  12. mod open;
  13. mod pwd;
  14. mod quote;
  15. mod segfault;
  16. mod sus;
  17. mod time;
  18. mod rick;
  19. pub struct BuiltinConfig {
  20. pub prompt_style: PromptStyle,
  21. }
  22. impl BuiltinConfig {
  23. pub fn new() -> Self {
  24. Self {
  25. prompt_style: PromptStyle::Default,
  26. }
  27. }
  28. }
  29. trait Builtin: Sync + Send {
  30. fn execute(&mut self, config: &mut BuiltinConfig, args: Vec<String>) -> Result<(), ShellError>;
  31. }
  32. const BUILTINS: Lazy<Vec<(&str, Box<dyn Builtin>)>> = Lazy::new(|| {
  33. vec![
  34. ("blahaj", Box::new(blahaj::Blahaj)),
  35. ("cd", Box::new(cd::Cd)),
  36. ("change-prompt", Box::new(change_prompt::ChangePrompt)),
  37. ("exit", Box::new(exit::Exit)),
  38. ("fetch", Box::new(fetch::Fetch)),
  39. ("help", Box::new(help::Help)),
  40. ("logout", Box::new(logout::Logout)),
  41. ("ls", Box::new(ls::Ls)),
  42. ("open", Box::new(open::Open)),
  43. ("pwd", Box::new(pwd::Pwd)),
  44. ("quote", Box::new(quote::Quote)),
  45. ("segfault", Box::new(segfault::Segfault)),
  46. ("sus", Box::new(sus::Sus)),
  47. ("time", Box::new(time::Time)),
  48. ("rick", Box::new(rick::Rick)),
  49. ]
  50. });
  51. pub fn is_builtin(keyword: &str) -> bool {
  52. BUILTINS.iter().find(|(k, _)| k == &keyword).is_some()
  53. }
  54. #[allow(const_item_mutation)]
  55. pub fn execute_builtin(
  56. keyword: &str,
  57. config: &mut BuiltinConfig,
  58. args: Vec<String>,
  59. ) -> Result<(), ShellError> {
  60. if let Some(builtin) = BUILTINS
  61. .iter_mut()
  62. .find_map(|(k, c)| if k == &keyword { Some(c) } else { None })
  63. {
  64. builtin.execute(config, args)?
  65. }
  66. Ok(())
  67. }
  68. #[cfg(test)]
  69. mod tests {
  70. use super::*;
  71. #[test]
  72. fn test_is_builtin_blahaj(){
  73. assert!(is_builtin("blahaj"));
  74. }
  75. }
  76. #[test]
  77. fn test_is_builtin_cd() {
  78. assert!(is_builtin("cd"));
  79. }
  80. #[test]
  81. fn test_is_builtin_change_prompt() {
  82. assert!(is_builtin("change-prompt"));
  83. }
  84. #[test]
  85. fn test_is_builtin_exit() {
  86. assert!(is_builtin("exit"));
  87. }
  88. #[test]
  89. fn test_is_builtin_fetch() {
  90. assert!(is_builtin("fetch"));
  91. }
  92. #[test]
  93. fn test_is_builtin_help() {
  94. assert!(is_builtin("help"));
  95. }
  96. #[test]
  97. fn test_is_builtin_logout() {
  98. assert!(is_builtin("logout"))
  99. }
  100. #[test]
  101. fn test_is_builtin_ls() {
  102. assert!(is_builtin("ls"));
  103. }
  104. #[test]
  105. fn test_is_builtin_open() {
  106. assert!(is_builtin("open"));
  107. }
  108. #[test]
  109. fn test_is_builtin_pwd() {
  110. assert!(is_builtin("pwd"));
  111. }
  112. #[test]
  113. fn test_is_builtin_quote() {
  114. assert!(is_builtin("quote"));
  115. }
  116. #[test]
  117. fn test_is_builtin_segfault() {
  118. assert!(is_builtin("segfault"));
  119. }
  120. #[test]
  121. fn test_is_builtin_sus() {
  122. assert!(is_builtin("sus"));
  123. }
  124. #[test]
  125. fn test_is_builtin_time() {
  126. assert!(is_builtin("time"));
  127. }
  128. #[test]
  129. fn test_is_builtin_notabuiltin() {
  130. assert!(!is_builtin("notabuiltin"))
  131. }