ability to overwrite and add to profile arguments from command line
This commit is contained in:
		
							
								
								
									
										18
									
								
								src/args.rs
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/args.rs
									
									
									
									
									
								
							@@ -112,12 +112,12 @@ pub struct ListOptions {
 | 
				
			|||||||
    /// Which columns to include.
 | 
					    /// Which columns to include.
 | 
				
			||||||
    #[clap(short, value_enum)]
 | 
					    #[clap(short, value_enum)]
 | 
				
			||||||
    pub column : Vec<Column>,
 | 
					    pub column : Vec<Column>,
 | 
				
			||||||
    /// Field to order by.
 | 
					    /// Field to order by [default: id].
 | 
				
			||||||
    #[clap(long, value_enum, default_value_t=OrderBy::Id)]
 | 
					    #[clap(long, value_enum)]
 | 
				
			||||||
    pub order_by : OrderBy,
 | 
					    pub order_by : Option<OrderBy>,
 | 
				
			||||||
    /// Sort ascending on descending.
 | 
					    /// Sort ascending on descending [default: asc].
 | 
				
			||||||
    #[clap(long, value_enum, default_value_t=Order::Asc)]
 | 
					    #[clap(long, value_enum)]
 | 
				
			||||||
    pub order : Order,
 | 
					    pub order : Option<Order>,
 | 
				
			||||||
    /// Tags to include.
 | 
					    /// Tags to include.
 | 
				
			||||||
    #[clap(short, long)]
 | 
					    #[clap(short, long)]
 | 
				
			||||||
    pub tag : Vec<String>,
 | 
					    pub tag : Vec<String>,
 | 
				
			||||||
@@ -150,14 +150,14 @@ pub struct ListOptions {
 | 
				
			|||||||
    pub no_dependents : bool,
 | 
					    pub no_dependents : bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
 | 
					#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
pub enum Order {
 | 
					pub enum Order {
 | 
				
			||||||
    #[default]
 | 
					    #[default]
 | 
				
			||||||
    Asc,
 | 
					    Asc,
 | 
				
			||||||
    Desc,
 | 
					    Desc,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Hash, Clone, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
 | 
					#[derive(Hash, Clone, Copy, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
pub enum Column {
 | 
					pub enum Column {
 | 
				
			||||||
    Due,
 | 
					    Due,
 | 
				
			||||||
    Priority,
 | 
					    Priority,
 | 
				
			||||||
@@ -167,7 +167,7 @@ pub enum Column {
 | 
				
			|||||||
    Status,
 | 
					    Status,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Default, Clone, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
 | 
					#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
pub enum OrderBy {
 | 
					pub enum OrderBy {
 | 
				
			||||||
    #[default]
 | 
					    #[default]
 | 
				
			||||||
    Id,
 | 
					    Id,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -171,13 +171,14 @@ fn program() -> Result<(), error::Error> {
 | 
				
			|||||||
                task.save()?;
 | 
					                task.save()?;
 | 
				
			||||||
                println!("Marked task {} as complete", format::id(id));
 | 
					                println!("Marked task {} as complete", format::id(id));
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            Command::List { profile, options } => {
 | 
					            Command::List { profile : profile_name, options : additional } => {
 | 
				
			||||||
                let options = match profile {
 | 
					                let options = match profile_name {
 | 
				
			||||||
                    Some(profile) => {
 | 
					                    Some(profile_name) => {
 | 
				
			||||||
                        config.get_profile(&profile)?
 | 
					                        let profile = config.get_profile(&profile_name)?;
 | 
				
			||||||
 | 
					                        ListOptions::combine(profile, &additional)
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    None => {
 | 
					                    None => {
 | 
				
			||||||
                        &options
 | 
					                        additional
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                tasks::list(options, vault_folder, &state)?;
 | 
					                tasks::list(options, vault_folder, &state)?;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										63
									
								
								src/tasks.rs
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								src/tasks.rs
									
									
									
									
									
								
							@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use crate::args;
 | 
				
			||||||
use crate::error;
 | 
					use crate::error;
 | 
				
			||||||
use crate::state;
 | 
					use crate::state;
 | 
				
			||||||
use crate::format;
 | 
					use crate::format;
 | 
				
			||||||
@@ -355,8 +356,50 @@ fn compare_due_dates<T : Ord>(first : &Option<T>, second : &Option<T>) -> cmp::O
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl args::ListOptions {
 | 
				
			||||||
 | 
					    /// Combines list options coming from a profile and from the additional arguments given. Order
 | 
				
			||||||
 | 
					    /// of the arguments provided matters, hence the argument names (because optional arguments
 | 
				
			||||||
 | 
					    /// from the profile are overwritten by the additional arguments).
 | 
				
			||||||
 | 
					    pub fn combine(profile : &Self, additional : &Self) -> Self {
 | 
				
			||||||
 | 
					        /// Joins two vectors together one after the other, creating a new allocation.
 | 
				
			||||||
 | 
					        fn concat<T : Clone>(a : &Vec<T>, b : &Vec<T>) -> Vec<T> {
 | 
				
			||||||
 | 
					            let mut a = a.clone();
 | 
				
			||||||
 | 
					            a.extend(b.iter().cloned());
 | 
				
			||||||
 | 
					            a
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Takes two options, and prioritises the second if it is provided in the output, using
 | 
				
			||||||
 | 
					        /// the first as a fallback, and returning None if both are None.
 | 
				
			||||||
 | 
					        fn join_options<T : Clone>(a : &Option<T>, b : &Option<T>) -> Option<T> {
 | 
				
			||||||
 | 
					            match (a, b) {
 | 
				
			||||||
 | 
					                (Some(_), Some(b)) => Some(b.clone()),
 | 
				
			||||||
 | 
					                (Some(a), None) => Some(a.clone()),
 | 
				
			||||||
 | 
					                (None, Some(b)) => Some(b.clone()),
 | 
				
			||||||
 | 
					                (None, None) => None,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            column : concat(&profile.column, &additional.column),
 | 
				
			||||||
 | 
					            order_by : join_options(&profile.order_by, &additional.order_by),
 | 
				
			||||||
 | 
					            order : join_options(&profile.order, &profile.order),
 | 
				
			||||||
 | 
					            tag : concat(&profile.tag, &additional.tag),
 | 
				
			||||||
 | 
					            exclude_tag : concat(&profile.exclude_tag, &additional.exclude_tag),
 | 
				
			||||||
 | 
					            priority : concat(&profile.priority, &additional.priority),
 | 
				
			||||||
 | 
					            due_before : join_options(&profile.due_before, &additional.due_before),
 | 
				
			||||||
 | 
					            due_after : join_options(&profile.due_after, &additional.due_after),
 | 
				
			||||||
 | 
					            created_before : join_options(&profile.created_before, &additional.created_before),
 | 
				
			||||||
 | 
					            created_after : join_options(&profile.created_after, &additional.created_after),
 | 
				
			||||||
 | 
					            include_completed : profile.include_completed || additional.include_completed,
 | 
				
			||||||
 | 
					            no_dependencies : profile.no_dependencies || additional.no_dependencies,
 | 
				
			||||||
 | 
					            no_dependents : profile.no_dependents || additional.no_dependents,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Lists all tasks in the specified vault.
 | 
					/// Lists all tasks in the specified vault.
 | 
				
			||||||
pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &state::State) -> Result<(), error::Error> {
 | 
					pub fn list(mut options : args::ListOptions, vault_folder : &path::Path, state : &state::State) -> Result<(), error::Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut table = comfy_table::Table::new();
 | 
					    let mut table = comfy_table::Table::new();
 | 
				
			||||||
    table
 | 
					    table
 | 
				
			||||||
@@ -446,9 +489,9 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Sort the tasks.
 | 
					    // Sort the tasks.
 | 
				
			||||||
    use super::{OrderBy, Order};
 | 
					    use super::{OrderBy, Order};
 | 
				
			||||||
    match options.order_by {
 | 
					    match options.order_by.unwrap_or_default() {
 | 
				
			||||||
        OrderBy::Id => {
 | 
					        OrderBy::Id => {
 | 
				
			||||||
            match options.order {
 | 
					            match options.order.unwrap_or_default() {
 | 
				
			||||||
                Order::Asc => {
 | 
					                Order::Asc => {
 | 
				
			||||||
                    tasks.sort_by(|t1, t2| t1.data.id.cmp(&t2.data.id));
 | 
					                    tasks.sort_by(|t1, t2| t1.data.id.cmp(&t2.data.id));
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -458,7 +501,7 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        OrderBy::Name => {
 | 
					        OrderBy::Name => {
 | 
				
			||||||
            match options.order {
 | 
					            match options.order.unwrap_or_default() {
 | 
				
			||||||
                Order::Asc => {
 | 
					                Order::Asc => {
 | 
				
			||||||
                    tasks.sort_by(|t1, t2| t1.data.name.cmp(&t2.data.name));
 | 
					                    tasks.sort_by(|t1, t2| t1.data.name.cmp(&t2.data.name));
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -468,7 +511,7 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        OrderBy::Due => {
 | 
					        OrderBy::Due => {
 | 
				
			||||||
            match options.order {
 | 
					            match options.order.unwrap_or_default() {
 | 
				
			||||||
                Order::Asc => {
 | 
					                Order::Asc => {
 | 
				
			||||||
                    tasks.sort_by(|t1, t2| compare_due_dates(&t1.data.due, &t2.data.due));
 | 
					                    tasks.sort_by(|t1, t2| compare_due_dates(&t1.data.due, &t2.data.due));
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -478,7 +521,7 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        OrderBy::Priority => {
 | 
					        OrderBy::Priority => {
 | 
				
			||||||
            match options.order {
 | 
					            match options.order.unwrap_or_default() {
 | 
				
			||||||
                Order::Asc => {
 | 
					                Order::Asc => {
 | 
				
			||||||
                    tasks.sort_by(|t1, t2| t1.data.priority.cmp(&t2.data.priority));
 | 
					                    tasks.sort_by(|t1, t2| t1.data.priority.cmp(&t2.data.priority));
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -488,7 +531,7 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        OrderBy::Created => {
 | 
					        OrderBy::Created => {
 | 
				
			||||||
            match options.order {
 | 
					            match options.order.unwrap_or_default() {
 | 
				
			||||||
                Order::Asc => {
 | 
					                Order::Asc => {
 | 
				
			||||||
                    tasks.sort_by(|t1, t2| t1.data.created.cmp(&t2.data.created));
 | 
					                    tasks.sort_by(|t1, t2| t1.data.created.cmp(&t2.data.created));
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -498,7 +541,7 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        OrderBy::Tracked => {
 | 
					        OrderBy::Tracked => {
 | 
				
			||||||
            match options.order {
 | 
					            match options.order.unwrap_or_default() {
 | 
				
			||||||
                Order::Asc => {
 | 
					                Order::Asc => {
 | 
				
			||||||
                    tasks.sort_by(|t1, t2| TimeEntry::total(&t1.data.time_entries).cmp(&TimeEntry::total(&t2.data.time_entries)));
 | 
					                    tasks.sort_by(|t1, t2| TimeEntry::total(&t1.data.time_entries).cmp(&TimeEntry::total(&t2.data.time_entries)));
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -513,7 +556,7 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
    let mut headers = vec!["Id", "Name"];
 | 
					    let mut headers = vec!["Id", "Name"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Remove duplicate columns.
 | 
					    // Remove duplicate columns.
 | 
				
			||||||
    let unique_columns : Vec<_> = {
 | 
					    options.column = {
 | 
				
			||||||
        let mut columns = HashSet::new();
 | 
					        let mut columns = HashSet::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        options.column.clone()
 | 
					        options.column.clone()
 | 
				
			||||||
@@ -531,7 +574,7 @@ pub fn list(options : &super::ListOptions, vault_folder : &path::Path, state : &
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    use super::Column;
 | 
					    use super::Column;
 | 
				
			||||||
    for column in &unique_columns {
 | 
					    for column in &options.column {
 | 
				
			||||||
        match column {
 | 
					        match column {
 | 
				
			||||||
            Column::Tracked => {
 | 
					            Column::Tracked => {
 | 
				
			||||||
                headers.push("Tracked");
 | 
					                headers.push("Tracked");
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user