Well, what and where can I provide you to understand why the program breaks,
As soon as I understand, I have three scenarios
- /target/release/hrdiff view dep
- /target/release/hrdiff view emp
- /target/release/hrdiff view user
when starting 1 and 2, I get the same error when running 3, I get some kind of result with users
here is the models.rs code
pub trait Objects {
fn all(&mut self, config: &Config);
}
extern crate serde_json;
use crate::config::Config;
use crate::rep::{get_deps, get_emps, get_users, write_user};
use ldap3::{LdapResult, SearchEntry};
use serde::Deserialize;
use std::collections::HashMap;
use std::fmt;
#[derive(Deserialize)]
#[allow(non_snake_case)]
pub struct Employee {
pub id: String,
pub Employee_id: String,
pub Name: EmployeeName,
pub Title: Title,
pub Manager: String,
pub Department: String,
pub state: String,
}
#[derive(Deserialize)]
#[allow(non_snake_case)]
pub struct EmployeeName {
pub Ru: String,
pub En: String,
}
#[derive(Deserialize)]
#[allow(non_snake_case)]
pub struct Title {
pub Ru: String,
pub En: String,
pub Kz: String,
}
impl Objects for HashMap<i32, Employee> {
fn all(&mut self, config: &Config) {
let emps = get_emps(&config).unwrap();
for emp in emps {
let key: i32 = emp.id.trim().parse().unwrap();
if let Some(_u) = self.get(&key) {
println!("Duplicating emp ID: {}", key);
} else {
self.insert(key, emp);
}
}
}
}
impl fmt::Display for Employee {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}, {}", self.Name.Ru, self.state)
}
}
#[derive(Deserialize)]
#[allow(non_snake_case)]
pub struct Dep {
pub id: String,
pub name: DepName,
pub Supervisor: String,
pub mvz: String,
}
#[derive(Deserialize)]
pub struct DepName {
pub ru: String,
pub en: String,
pub kz: String,
}
impl Objects for HashMap<i32, Dep> {
fn all(&mut self, config: &Config) {
let deps = get_deps(&config).unwrap();
for dep in deps {
let key: i32 = dep.id.trim().parse().unwrap();
if let Some(_u) = self.get(&key) {
println!("Duplicating dep ID: {}", key);
} else {
self.insert(key, dep);
}
}
}
}
impl fmt::Display for Dep {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name.ru)
}
}
pub struct User {
pub id: i32,
pub employee_id: String,
pub name_ru: String,
pub name_en: String,
pub title_ru: String,
pub title_en: String,
pub title_kz: String,
pub manager: i32,
pub manager_dn: String,
pub department: i32,
pub department_ru: String,
pub department_en: String,
pub department_kz: String,
pub mvz: String,
pub dn: String,
}
impl User {
fn default() -> User {
User {
id: 0,
employee_id: String::from(""),
name_ru: String::from(""),
name_en: String::from(""),
title_ru: String::from(""),
title_en: String::from(""),
title_kz: String::from(""),
manager: 0,
manager_dn: String::from(""),
department: 0,
department_ru: String::from(""),
department_en: String::from(""),
department_kz: String::from(""),
mvz: String::from(""),
dn: String::from(""),
}
}
fn new(user: &SearchEntry) -> User {
let mut result = User::default();
if let Some(v) = user.attrs.get("employeeID") {
println!("{}", v[0]);
result.id = v[0].parse().unwrap();
}
if let Some(v) = user.attrs.get("employeeNumber") {
result.employee_id = v[0].clone();
}
if let Some(v) = user.attrs.get("extensionAttribute4") {
result.name_ru = v[0].clone();
}
if let Some(v) = user.attrs.get("cn") {
result.name_en = v[0].clone();
}
if let Some(v) = user.attrs.get("extensionAttribute6") {
result.title_ru = v[0].clone();
}
if let Some(v) = user.attrs.get("title") {
result.title_en = v[0].clone();
}
if let Some(v) = user.attrs.get("extensionAttribute5") {
result.title_kz = v[0].clone();
}
if let Some(v) = user.attrs.get("extensionAttribute10") {
result.manager = v[0].trim().parse().unwrap();
}
if let Some(v) = user.attrs.get("manager") {
result.manager_dn = v[0].clone();
}
if let Some(v) = user.attrs.get("department") {
result.department_en = v[0].clone();
}
if let Some(v) = user.attrs.get("extensionAttribute12") {
result.department_ru = v[0].clone();
}
if let Some(v) = user.attrs.get("extensionAttribute11") {
result.department_kz = v[0].clone();
}
if let Some(v) = user.attrs.get("departmentNumber") {
result.department = v[0].parse().unwrap();
}
if let Some(v) = user.attrs.get("mVZ") {
result.mvz = v[0].clone();
}
result.dn = user.dn.clone();
result
}
}
impl Objects for HashMap<i32, User> {
fn all(&mut self, config: &Config) {
let users = get_users(&config).unwrap();
for user in users {
let plain_user = User::new(&user);
if let Some(_u) = self.get(&plain_user.id) {
println!("Duplicating user ID: {}", plain_user.id);
} else {
self.insert(plain_user.id, plain_user);
}
}
}
}
impl fmt::Display for User {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name_ru)
}
}
pub struct Replace(pub String, pub String, pub String);
pub struct Diff {
pub dn: String,
pub replace: Vec<Replace>,
}
impl Diff {
pub fn push_changes(&self, config: &Config) -> LdapResult {
write_user(&config, &self.dn, &self.replace).unwrap()
}
}
impl Objects for HashMap<String, Diff> {
fn all(&mut self, config: &Config) {
let mut users_hash: HashMap<i32, User> = HashMap::new();
users_hash.all(&config);
let mut emps_hash: HashMap<i32, Employee> = HashMap::new();
emps_hash.all(&config);
let mut deps_hash: HashMap<i32, Dep> = HashMap::new();
deps_hash.all(&config);
for (_id, user) in &users_hash {
if let Some(emp) = emps_hash.get(&user.id) {
if emp.state != "work" {
println!("Need to disable user with ID: {}, {}", &user.id, &user.name_en);
};
let dep_id: i32 = emp.Department.trim().parse().unwrap();
if let Some(dep) = deps_hash.get(&dep_id) {
let mut user_diff = Diff {
dn: user.dn.clone(),
replace: vec![],
};
if user.employee_id != emp.Employee_id.trim() {
let attr = String::from("employeeNumber");
let old = user.employee_id.clone();
let new = emp.Employee_id.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.name_ru != emp.Name.Ru.trim() {
let attr = String::from("extensionAttribute4");
let old = user.name_ru.clone();
let new = emp.Name.Ru.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.title_ru != emp.Title.Ru.trim() {
let attr = String::from("extensionAttribute6");
let old = user.title_ru.clone();
let new = emp.Title.Ru.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.title_en != emp.Title.En.trim() {
let attr = String::from("title");
let old = user.title_en.clone();
let new = emp.Title.En.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.title_kz != emp.Title.Kz.trim() {
let attr = String::from("extensionAttribute5");
let old = user.title_kz.clone();
let new = emp.Title.Kz.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.department_en != dep.name.en.trim() {
let attr = String::from("department");
let old = user.department_en.clone();
let new = dep.name.en.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.department_ru != dep.name.ru.trim() {
let attr = String::from("extensionAttribute12");
let old = user.department_ru.clone();
let new = dep.name.ru.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.department_kz != dep.name.kz.trim() {
let attr = String::from("extensionAttribute11");
let old = user.department_kz.clone();
let new = dep.name.kz.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.department != dep_id {
let attr = String::from("departmentNumber");
let old = user.department.to_string();
let new = dep_id.to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if user.mvz != dep.mvz.trim() {
let attr = String::from("mVZ");
let old = user.mvz.clone();
let new = dep.mvz.trim().clone().to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if let Ok(manager_id) = emp.Manager.trim().parse::<i32>() {
if user.manager != manager_id {
let attr = String::from("extensionAttribute10");
let old = user.manager.to_string();
let new = manager_id.to_string();
user_diff.replace.push(Replace(attr, old, new));
}
if let Some(manager) = users_hash.get(&manager_id) {
if user.manager_dn != manager.dn {
let attr = String::from("manager");
let old = user.manager_dn.clone();
let new = manager.dn.clone();
user_diff.replace.push(Replace(attr, old, new));
}
} else {
// Если не удалось найти менеджера в LDAP по табельному, то ищем по employeeNumber
if let Some(hr_manager) = emps_hash.get(&manager_id) {
let wd = hr_manager.Employee_id.trim();
if let Some(ldap_manager) =
users_hash.iter().find(|(_key, man)| man.employee_id == wd)
{
let (_id, manager_by_wd) = ldap_manager;
if user.manager_dn != manager_by_wd.dn {
let attr = String::from("manager");
let old = user.manager_dn.clone();
let new = manager_by_wd.dn.clone();
user_diff.replace.push(Replace(attr, old, new));
}
} else {
println!(
"Unable to find manager in LDAP with employeeNumber: {}",
wd
);
}
} else {
println!("Unable to find manager in HR with ID: {}", manager_id);
}
}
}
if user_diff.replace.len() > 0 {
self.insert(user.dn.clone(), user_diff);
}
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn get_emps_hash() {
let config = Config::new().unwrap();
let mut emps_hash: HashMap<i32, Employee> = HashMap::new();
emps_hash.all(&config);
assert_ne!(emps_hash.len(), 0)
}
#[test]
fn get_deps_hash() {
let config = Config::new().unwrap();
let mut deps_hash: HashMap<i32, Dep> = HashMap::new();
deps_hash.all(&config);
assert_ne!(deps_hash.len(), 0)
}
#[test]
fn get_users_hash() {
let config = Config::new().unwrap();
let mut users_hash: HashMap<i32, User> = HashMap::new();
users_hash.all(&config);
assert_ne!(users_hash.len(), 0)
}
#[test]
fn get_diff_hash() {
let config = Config::new().unwrap();
let mut diff_hash: HashMap<String, Diff> = HashMap::new();
diff_hash.all(&config);
assert_ne!(diff_hash.len(), 0)
}
}