<commit_before>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

use std::collections::{HashMap, HashSet};
use std::fs;
use std::path::{Path, PathBuf};

use album::Album;
use audit::{audit_get_str_value, Report, Reporter, SkipReason};
use folder::Folder;
use keyword::{parse_keywords, Keyword};
use master::Master;
use plist::Value;
use plutils;
use store;
use version::Version;
use AplibObject;
use PlistLoadable;

// This is mostly from db_version = 110

const INFO_PLIST: &str = "Info.plist";

const BUNDLE_IDENTIFIER: &str = "com.apple.Aperture.library";

const DATABASE_DIR: &str = "Database";

// in Database
const DATAMODEL_VERSION_PLIST: &str = "DataModelVersion.plist";
const KEYWORDS_PLIST: &str = "Keywords.plist";
const ALBUMS_DIR: &str = "Albums";
const FOLDERS_DIR: &str = "Folders";
const VERSIONS_BASE_DIR: &str = "Versions";

/// Info of the library data model
pub struct ModelInfo {
    pub is_iphoto_library: Option<bool>,
    pub db_version: Option<i64>,
    pub db_minor_back_compatible_version: Option<i64>,
    pub db_minor_version: Option<i64>,
    pub db_uuid: Option<String>,
    pub create_date: Option<String>,
    pub image_io_version: Option<String>,
    pub raw_camera_bundle_version: Option<String>,
    pub touched_by_aperture: Option<bool>,
    pub master_count: Option<i64>,
    pub version_count: Option<i64>,
    pub project_compat_back_to_version: Option<i64>,
    pub project_version: Option<i64>,
}

impl ModelInfo {
    fn parse(plist: &Value) -> Option<ModelInfo> {
        use plutils::{get_bool_value, get_int_value, get_str_value};

        match *plist {
            Value::Dictionary(ref dict) => Some(ModelInfo {
                db_uuid: get_str_value(dict, "databaseUuid"),
                db_minor_back_compatible_version: get_int_value(
                    dict,
                    "DatabaseCompatibleBackToMinorVersion",
                ),
                db_minor_version: get_int_value(dict, "DatabaseMinorVersion"),
                db_version: get_int_value(dict, "DatabaseVersion"),
                is_iphoto_library: get_bool_value(dict, "isIPhotoLibrary"),
                create_date: get_str_value(dict, "createDate"),
                image_io_version: get_str_value(dict, "imageIOVersion"),
                raw_camera_bundle_version: get_str_value(dict, "rawCameraBundleVersion"),
                touched_by_aperture: get_bool_value(dict, "touchedByAperture"),
                master_count: get_int_value(dict, "masterCount"),
                version_count: get_int_value(dict, "versionCount"),
                project_version: get_int_value(dict, "projectVersion"),
                project_compat_back_to_version: get_int_value(
                    dict,
                    "projectCompatibleBackToVersion",
                ),
            }),
            _ => None,
        }
    }
}

/// Library is the Aperture library.
pub struct Library {
    /// The path to the .aplib bundle (the directory)
    path: String,

    /// It's version string (displayed by get info in the Finder)
    version: String,

    /// All the folders UUID
    folders: HashSet<String>,
    /// All the albums UUID
    albums: HashSet<String>,
    //    keywords: HashSet<String>,
    /// All the masters UUID
    masters: HashSet<String>,
    /// All the version UUID
    versions: HashSet<String>,

    /// The object store. The key is the UUID
    objects: HashMap<String, store::Wrapper>,
    /// Auditor for the audit mode.
    auditor: Option<Reporter>,
}

impl Library {
    /// Create a new library object from the exist path to
    /// the bundle directory.
    pub fn new(p: &str) -> Library {
        Library {
            path: p.to_owned(),
            version: String::new(),

            folders: HashSet::new(),
            albums: HashSet::new(),
            //            keywords: HashSet::new(),
            masters: HashSet::new(),
            versions: HashSet::new(),

            objects: HashMap::new(),
            auditor: None,
        }
    }

    /// Set an auditor.
    pub fn set_auditor(&mut self, auditor: Option<Reporter>) {
        self.auditor = auditor;
    }
    /// Get the auditor
    pub fn get_auditor(&self) -> Option<&Reporter> {
        self.auditor.as_ref()
    }

    /// Store the wrapped object.
    /// Return true if the object was stored
    /// Return false if there already was an object with the same uuid
    /// or if the uuid in invalid.
    pub fn store(&mut self, obj: store::Wrapper) -> bool {
        let uuid_str = {
            let uuid = obj.uuid();
            if uuid.is_none() {
                return false;
            }
            uuid.unwrap().to_owned()
        };
        match self.objects.insert(uuid_str, obj) {
            None => true,
            _ => false,
        }
    }<commit_msg>fix clippy issues<commit_after>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

use std::collections::{HashMap, HashSet};
use std::fs;
use std::path::{Path, PathBuf};

use album::Album;
use audit::{audit_get_str_value, Report, Reporter, SkipReason};
use folder::Folder;
use keyword::{parse_keywords, Keyword};
use master::Master;
use plist::Value;
use plutils;
use store;
use version::Version;
use AplibObject;
use PlistLoadable;

// This is mostly from db_version = 110

const INFO_PLIST: &str = "Info.plist";

const BUNDLE_IDENTIFIER: &str = "com.apple.Aperture.library";

const DATABASE_DIR: &str = "Database";

// in Database
const DATAMODEL_VERSION_PLIST: &str = "DataModelVersion.plist";
const KEYWORDS_PLIST: &str = "Keywords.plist";
const ALBUMS_DIR: &str = "Albums";
const FOLDERS_DIR: &str = "Folders";
const VERSIONS_BASE_DIR: &str = "Versions";

/// Info of the library data model
pub struct ModelInfo {
    pub is_iphoto_library: Option<bool>,
    pub db_version: Option<i64>,
    pub db_minor_back_compatible_version: Option<i64>,
    pub db_minor_version: Option<i64>,
    pub db_uuid: Option<String>,
    pub create_date: Option<String>,
    pub image_io_version: Option<String>,
    pub raw_camera_bundle_version: Option<String>,
    pub touched_by_aperture: Option<bool>,
    pub master_count: Option<i64>,
    pub version_count: Option<i64>,
    pub project_compat_back_to_version: Option<i64>,
    pub project_version: Option<i64>,
}

impl ModelInfo {
    fn parse(plist: &Value) -> Option<ModelInfo> {
        use plutils::{get_bool_value, get_int_value, get_str_value};

        match *plist {
            Value::Dictionary(ref dict) => Some(ModelInfo {
                db_uuid: get_str_value(dict, "databaseUuid"),
                db_minor_back_compatible_version: get_int_value(
                    dict,
                    "DatabaseCompatibleBackToMinorVersion",
                ),
                db_minor_version: get_int_value(dict, "DatabaseMinorVersion"),
                db_version: get_int_value(dict, "DatabaseVersion"),
                is_iphoto_library: get_bool_value(dict, "isIPhotoLibrary"),
                create_date: get_str_value(dict, "createDate"),
                image_io_version: get_str_value(dict, "imageIOVersion"),
                raw_camera_bundle_version: get_str_value(dict, "rawCameraBundleVersion"),
                touched_by_aperture: get_bool_value(dict, "touchedByAperture"),
                master_count: get_int_value(dict, "masterCount"),
                version_count: get_int_value(dict, "versionCount"),
                project_version: get_int_value(dict, "projectVersion"),
                project_compat_back_to_version: get_int_value(
                    dict,
                    "projectCompatibleBackToVersion",
                ),
            }),
            _ => None,
        }
    }
}

/// Library is the Aperture library.
pub struct Library {
    /// The path to the .aplib bundle (the directory)
    path: String,

    /// It's version string (displayed by get info in the Finder)
    version: String,

    /// All the folders UUID
    folders: HashSet<String>,
    /// All the albums UUID
    albums: HashSet<String>,
    //    keywords: HashSet<String>,
    /// All the masters UUID
    masters: HashSet<String>,
    /// All the version UUID
    versions: HashSet<String>,

    /// The object store. The key is the UUID
    objects: HashMap<String, store::Wrapper>,
    /// Auditor for the audit mode.
    auditor: Option<Reporter>,
}

impl Library {
    /// Create a new library object from the exist path to
    /// the bundle directory.
    pub fn new(p: &str) -> Library {
        Library {
            path: p.to_owned(),
            version: String::new(),

            folders: HashSet::new(),
            albums: HashSet::new(),
            //            keywords: HashSet::new(),
            masters: HashSet::new(),
            versions: HashSet::new(),

            objects: HashMap::new(),
            auditor: None,
        }
    }

    /// Set an auditor.
    pub fn set_auditor(&mut self, auditor: Option<Reporter>) {
        self.auditor = auditor;
    }
    /// Get the auditor
    pub fn get_auditor(&self) -> Option<&Reporter> {
        self.auditor.as_ref()
    }

    /// Store the wrapped object.
    /// Return true if the object was stored
    /// Return false if there already was an object with the same uuid
    /// or if the uuid in invalid.
    pub fn store(&mut self, obj: store::Wrapper) -> bool {
        if let Some(uuid_str) = obj.uuid() {
            match self.objects.insert(uuid_str, obj) {
                None => true,
                _ => false,
            }
        } else {
            false
        }
    }
{'fraction_non_alphanumeric': 0.11130275974025974, 'fraction_numerical': 0.004261363636363636, 'mean_word_length': 2.4428920712539295, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2043365', 'n_tokens_mistral': 3038, 'n_tokens_neox': 2939, 'n_words': 794}