Added planning load module and updated dependencies

A new module 'planning_load' has been added to the 'planning' directory, handling workload planning tasks. Updates have also been made to project dependencies in Cargo.lock and Cargo.toml. The added dependencies are necessary for the new functionalities in the 'planning_load' module. Also, a few adjustments were made to allow better access and error handling across packages.
This commit is contained in:
Julien Fastré 2024-05-22 23:05:43 +02:00
parent 0c3320943e
commit b49c08aed3
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
8 changed files with 220 additions and 3 deletions

83
Cargo.lock generated
View File

@ -64,6 +64,12 @@ version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
[[package]]
name = "bytecount"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -110,10 +116,12 @@ version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"gitlab", "gitlab",
"iso8601",
"log", "log",
"reqwest", "reqwest",
"serde", "serde",
"simple-home-dir", "simple-home-dir",
"tabled",
"tokio", "tokio",
"toml", "toml",
"url", "url",
@ -750,6 +758,16 @@ dependencies = [
"windows-sys 0.45.0", "windows-sys 0.45.0",
] ]
[[package]]
name = "iso8601"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153"
dependencies = [
"nom",
"serde",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.10.5" version = "0.10.5"
@ -959,6 +977,17 @@ version = "6.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
[[package]]
name = "papergrid"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ad43c07024ef767f9160710b3a6773976194758c7919b17e63b863db0bdf7fb"
dependencies = [
"bytecount",
"fnv",
"unicode-width",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.2.0" version = "2.2.0"
@ -983,6 +1012,30 @@ version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn 1.0.109",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.79" version = "1.0.79"
@ -1335,6 +1388,30 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "tabled"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c998b0c8b921495196a48aabaf1901ff28be0760136e31604f7967b0792050e"
dependencies = [
"papergrid",
"tabled_derive",
"unicode-width",
]
[[package]]
name = "tabled_derive"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c138f99377e5d653a371cdad263615634cfc8467685dfe8e73e2b8e98f44b17"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.9.0" version = "3.9.0"
@ -1586,6 +1663,12 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "void" name = "void"
version = "1.0.2" version = "1.0.2"

View File

@ -15,3 +15,5 @@ url = "2.3.1"
tokio = { version = "1.0.0", features = ["rt", "rt-multi-thread", "macros"] } tokio = { version = "1.0.0", features = ["rt", "rt-multi-thread", "macros"] }
simple-home-dir = "0.2.1" simple-home-dir = "0.2.1"
log = "0.4.17" log = "0.4.17"
tabled = "0.15.0"
iso8601 = { version = "0.6.1" , features = ["serde"]}

View File

@ -21,6 +21,7 @@ pub(crate) enum Commands {
#[derive(Subcommand)] #[derive(Subcommand)]
pub(crate) enum Planning { pub(crate) enum Planning {
I2work(Issue2Work), I2work(Issue2Work),
Load,
} }
#[derive(Args, Debug)] #[derive(Args, Debug)]

View File

@ -48,6 +48,7 @@ async fn main() {
let result = match cli.command { let result = match cli.command {
Some(Planning(I2work(args))) => planning::issue2work::issue2work(config, &args).await, Some(Planning(I2work(args))) => planning::issue2work::issue2work(config, &args).await,
Some(Planning(cli::Planning::Load)) => planning::planning_load::planning_load(config).await,
Some(Test) => debug::debug(config).await, Some(Test) => debug::debug(config).await,
None => Err(GeneralError { None => Err(GeneralError {
description: "No command launched".to_string(), description: "No command launched".to_string(),

View File

@ -6,8 +6,8 @@ use serde::Deserialize;
use std::error::Error; use std::error::Error;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
pub(crate) struct OpenProjectError { pub struct OpenProjectError {
pub(crate) description: String, pub description: String,
} }
impl From<reqwest::Error> for OpenProjectError { impl From<reqwest::Error> for OpenProjectError {

View File

@ -1,3 +1,6 @@
use crate::openproject::client::{handle_response_status, Client, OpenProjectError};
use crate::openproject::hal::Link;
use iso8601::Duration;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
@ -19,8 +22,119 @@ pub struct DescriptionWriter {
pub(crate) raw: String, pub(crate) raw: String,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug, Clone)]
pub struct WorkPackage { pub struct WorkPackage {
pub id: u64, pub id: u64,
pub subject: String, pub subject: String,
#[serde(alias = "estimatedTime")]
pub estimated_time: Option<Duration>,
#[serde(alias = "spentTime")]
pub spent_time: Option<Duration>,
}
#[derive(Deserialize, Debug)]
pub struct WorkPackageCollectionLinks {
#[serde(alias = "nextByOffset")]
pub next_by_offset: Option<Link>,
}
#[derive(Deserialize, Debug)]
pub struct WorkPackagesElements {
pub elements: Vec<WorkPackage>,
}
#[derive(Deserialize, Debug)]
pub struct WorkPackageCollection {
pub total: u64,
pub count: u64,
pub offset: u64,
#[serde(alias = "pageSize")]
pub page_size: u64,
#[serde(alias = "_links")]
pub links: WorkPackageCollectionLinks,
#[serde(alias = "_embedded")]
pub embedded: WorkPackagesElements,
}
impl WorkPackageCollection {
pub fn has_next(&self) -> bool {
self.links.next_by_offset.is_some()
}
pub fn is_last(&self) -> bool {
!self.has_next()
}
}
pub trait WorkPackageCollectionClient {
async fn work_package(&self) -> Result<Vec<WorkPackage>, OpenProjectError>;
}
trait GetWorkPackageCollectionClient {
async fn first_work_packages_collection(
&self,
) -> Result<WorkPackageCollection, OpenProjectError>;
async fn next_work_packages_collection(
&self,
current: &WorkPackageCollection,
) -> Result<WorkPackageCollection, OpenProjectError>;
}
impl GetWorkPackageCollectionClient for Client {
async fn first_work_packages_collection(
&self,
) -> Result<WorkPackageCollection, OpenProjectError> {
let client = reqwest::Client::new();
let response = client
.get(format!("{}/api/v3/work_packages", self.base_url))
.basic_auth("apikey", Some(&self.token))
.send()
.await?;
let collection = handle_response_status(response, "could not find work packages").await?;
Ok(collection)
}
async fn next_work_packages_collection(
&self,
current: &WorkPackageCollection,
) -> Result<WorkPackageCollection, OpenProjectError> {
let client = reqwest::Client::new();
let response = client
.get(format!(
"{}/{}",
self.base_url,
current.links.next_by_offset.clone().unwrap().href
))
.basic_auth("apikey", Some(&self.token))
.send()
.await?;
let collection = handle_response_status(response, "could not find work packages").await?;
Ok(collection)
}
}
impl WorkPackageCollectionClient for Client {
async fn work_package(&self) -> Result<Vec<WorkPackage>, OpenProjectError> {
let mut work_packages: Vec<WorkPackage> = vec![];
let mut collection = self.first_work_packages_collection().await?;
for w in collection.embedded.elements.iter_mut() {
work_packages.push(w.clone());
}
while !collection.is_last() {
collection = self.next_work_packages_collection(&collection).await?;
for w in collection.embedded.elements.iter() {
work_packages.push(w.clone());
}
}
Ok(work_packages)
}
} }

View File

@ -1 +1,2 @@
pub(crate) mod issue2work; pub(crate) mod issue2work;
pub(crate) mod planning_load;

View File

@ -0,0 +1,15 @@
use crate::config::Config;
use crate::error::GeneralError;
use crate::openproject::client::Client;
use crate::openproject::work::WorkPackageCollectionClient;
pub async fn planning_load(config: Config) -> Result<(), GeneralError> {
let open_project_client = Client::from_config(&config.openproject);
let work_packages = open_project_client.work_package().await?;
for w in work_packages {
println!("{:?}", w);
}
Ok(())
}