dotfiles_actions/create/
directive.rs

1// Copyright (c) 2021-2022 Miguel Barreto and others
2//
3// Permission is hereby granted, free of charge, to any person obtaining
4// a copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to
8// permit persons to whom the Software is furnished to do so, subject to
9// the following conditions:
10//
11// The above copyright notice and this permission notice shall be
12// included in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22//! This module defines [CreateDirective].
23extern crate strict_yaml_rust;
24
25use crate::create::action::CreateAction;
26use crate::filesystem::FileSystemDirective;
27use dotfiles_core::action::ActionParser;
28use dotfiles_core::action::SKIP_IN_CI_SETTING;
29use dotfiles_core::directive::DirectiveData;
30use dotfiles_core::directive::HasDirectiveData;
31use dotfiles_core::error::DotfilesError;
32use dotfiles_core::settings::initialize_settings_object;
33use dotfiles_core::settings::Setting;
34use dotfiles_core::yaml_util;
35use dotfiles_core_macros::Directive;
36use filesystem::FakeFileSystem;
37use filesystem::FileSystem;
38use filesystem::OsFileSystem;
39use std::marker::PhantomData;
40use std::path::Path;
41
42use strict_yaml_rust::StrictYaml;
43
44/// Constant for the name of the `create` directive.
45pub const DIRECTIVE_NAME: &str = "create";
46/// Constant for the name of the [`create_parent_dirs`](CreateAction::create_parent_dirs) Setting
47/// which forces to create all parent directories if necessary.
48pub const CREATE_PARENT_DIRS_SETTING: &str = "create_parent_dirs";
49/// Constant for the name of the [`directory`](CreateAction::directory) argument that contains the
50/// name of the directory to create
51pub const DIR_SETTING: &str = "dir";
52
53/// Initializes the default configuration for the [CreateDirective]
54pub fn init_directive_data() -> DirectiveData {
55  DirectiveData::from(
56    DIRECTIVE_NAME.into(),
57    initialize_settings_object(&[
58      (
59        CREATE_PARENT_DIRS_SETTING.to_owned(),
60        Setting::Boolean(false),
61      ),
62      (SKIP_IN_CI_SETTING.to_owned(), Setting::Boolean(false)),
63    ]),
64  )
65}
66
67/// A directive that can build [CreateAction]s to create directories in the filesystem.
68#[derive(Directive, Clone)]
69pub struct CreateDirective<'a, F: FileSystem + Default> {
70  fs: F,
71  data: DirectiveData,
72  phantom: PhantomData<&'a F>,
73}
74/// [CreateDirective] that uses the native [OsFileSystem].
75pub type NativeCreateDirective<'a> = CreateDirective<'a, OsFileSystem>;
76/// [CreateDirective] that uses the native [FakeFileSystem] for testing.
77pub type FakeCreateDirective<'a> = CreateDirective<'a, FakeFileSystem>;
78
79impl<'a, F: FileSystem + Default> FileSystemDirective<'a, F> for CreateDirective<'a, F> {
80  fn fs(&self) -> &F {
81    &self.fs
82  }
83
84  fn mut_fs(&mut self) -> &mut F {
85    &mut self.fs
86  }
87}
88
89impl<'a, F: FileSystem + Default> Default for CreateDirective<'a, F> {
90  fn default() -> Self {
91    Self {
92      fs: Default::default(),
93      data: init_directive_data(),
94      phantom: Default::default(),
95    }
96  }
97}
98
99impl<'a, F: FileSystem + Default> ActionParser<'a> for CreateDirective<'a, F> {
100  type ActionType = CreateAction<'a, F>;
101
102  fn parse_action(
103    &'a self,
104    settings: &std::collections::HashMap<String, Setting>,
105    yaml: &StrictYaml,
106    current_dir: &Path,
107  ) -> Result<CreateAction<'a, F>, DotfilesError> {
108    CreateAction::<'a, F>::new(
109      self.fs(),
110      yaml_util::get_boolean_setting_from_yaml_or_context(
111        SKIP_IN_CI_SETTING,
112        yaml,
113        settings,
114        self.defaults(),
115      )?,
116      yaml_util::get_string_content_or_keyed_value(yaml, Some(DIR_SETTING))?,
117      yaml_util::get_boolean_setting_from_yaml_or_context(
118        CREATE_PARENT_DIRS_SETTING,
119        yaml,
120        settings,
121        self.defaults(),
122      )?,
123      current_dir.to_owned(),
124    )
125  }
126}