<commit_before>//! FFI bindings and Rust wrappers for [libfswatch](https://github.com/emcrisostomo/fswatch).

#![allow(non_camel_case_types)]

extern crate libc;
#[cfg(feature = "use_time")]
extern crate time;

use libc::{c_uint, c_void, c_double};
use std::ops::Drop;
use std::ffi::{CString, CStr};
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::cell::Cell;

#[cfg(test)]
mod test;

pub mod ffi;

type FswResult<T> = Result<T, FswError>;

/// An error in the library.
#[derive(Debug)]
pub enum FswError {
  /// An error from fswatch.
  FromFsw(FswStatus),
  /// An error encountered when working with C strings.
  NulError(std::ffi::NulError),
  /// An error indicating that required parameters were missing.
  MissingRequiredParameters
}

/// Status codes from fswatch.
///
/// Most operations return a status code, either `Ok` or an error. A successful operation that
/// returns `Ok` is represented by returning `Ok(T)`, where `T` is data returned, if any. If no data
/// is returned, `()` is `T`.
///
/// Errors are represented by `Err(FswStatus)`, with the status returned by the operation being
/// directly available inside the `Err`.
#[derive(Debug, PartialEq)]
pub enum FswStatus {
  /// No error.
  Ok,
  /// Occasionally used by the Rust library to denote errors without status codes in fswatch.
  UnknownError,
  SessionUnknown,
  MonitorAlreadyExists,
  Memory,
  UnknownMonitorType,
  CallbackNotSet,
  PathsNotSet,
  MissingContext,
  InvalidPath,
  InvalidCallback,
  InvalidLatency,
  InvalidRegex,
  MonitorAlreadyRunning,
  UnknownValue,
  InvalidProprety
}

impl From<ffi::FSW_STATUS> for FswStatus {
  /// Converts from the `FSW_STATUS` type into the Rust `FswStatus`.
  ///
  /// This should never need to be used if utilizing the Rust wrappers. If given an invalid code,
  /// this will default to `UnknownError`.
  fn from(status: ffi::FSW_STATUS) -> FswStatus {
    match status {
      ffi::FSW_OK => FswStatus::Ok,
      ffi::FSW_ERR_SESSION_UNKNOWN => FswStatus::SessionUnknown,
      ffi::FSW_ERR_MONITOR_ALREADY_EXISTS => FswStatus::MonitorAlreadyExists,
      ffi::FSW_ERR_MEMORY => FswStatus::Memory,
      ffi::FSW_ERR_UNKNOWN_MONITOR_TYPE => FswStatus::UnknownMonitorType,
      ffi::FSW_ERR_CALLBACK_NOT_SET => FswStatus::CallbackNotSet,
      ffi::FSW_ERR_PATHS_NOT_SET => FswStatus::PathsNotSet,
      ffi::FSW_ERR_MISSING_CONTEXT => FswStatus::MissingContext,
      ffi::FSW_ERR_INVALID_PATH => FswStatus::InvalidPath,
      ffi::FSW_ERR_INVALID_CALLBACK => FswStatus::InvalidCallback,
      ffi::FSW_ERR_INVALID_LATENCY => FswStatus::InvalidLatency,
      ffi::FSW_ERR_INVALID_REGEX => FswStatus::InvalidRegex,
      ffi::FSW_ERR_MONITOR_ALREADY_RUNNING => FswStatus::MonitorAlreadyRunning,
      ffi::FSW_ERR_UNKNOWN_VALUE => FswStatus::UnknownValue,
      ffi::FSW_ERR_INVALID_PROPERTY => FswStatus::InvalidProprety,
      ffi::FSW_ERR_UNKNOWN_ERROR | _ => FswStatus::UnknownError
    }
  }
}

/// The various possible monitors that fswatch can utilize.
#[derive(Debug, PartialEq)]
#[repr(C)]
pub enum FswMonitorType {
  SystemDefault,
  FSEvents,
  KQueue,
  INotify,
  Windows,
  Poll,
  Fen
}

/// Flags denoting the operation(s) within an event.
#[derive(Debug, PartialEq, Clone)]
#[repr(u32)]
pub enum FswEventFlag {
  NoOp = 0,
  PlatformSpecific = 1,
  Created = (1 << 1),
  Updated = (1 << 2),
  Removed = (1 << 3),
  Renamed = (1 << 4),
  OwnerModified = (1 << 5),
  AttributeModified = (1 << 6),
  MovedFrom = (1 << 7),
  MovedTo = (1 << 8),
  IsFile = (1 << 9),
  IsDir = (1 << 10),
  IsSymLink = (1 << 11),
  Link = (1 << 12),
  Overflow = (1 << 13)
}

/// A monitor filter.
#[derive(Debug)]
pub struct FswMonitorFilter {
  /// A regular expression to match paths against.
  pub text: String,
  /// The type of filter.
  pub filter_type: FswFilterType,
  /// Whether the filter should be case sensitive.
  pub case_sensitive: bool,
  pub extended: bool
}

impl FswMonitorFilter {
  pub fn new(text: String, filter_type: FswFilterType, case_sensitive: bool, extended: bool) -> Self {
    FswMonitorFilter {
      text: text,
      filter_type: filter_type,
      case_sensitive: case_sensitive,
      extended: extended
    }
  }
}

/// A filter type.
#[derive(Debug)]
#[repr(C)]
pub enum FswFilterType {
  Include,
  Exclude
}
<commit_msg>refactor: accept AsRef<str> for FswMonitorFilter<commit_after>//! FFI bindings and Rust wrappers for [libfswatch](https://github.com/emcrisostomo/fswatch).

#![allow(non_camel_case_types)]

extern crate libc;
#[cfg(feature = "use_time")]
extern crate time;

use libc::{c_uint, c_void, c_double};
use std::ops::Drop;
use std::ffi::{CString, CStr};
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::cell::Cell;

#[cfg(test)]
mod test;

pub mod ffi;

type FswResult<T> = Result<T, FswError>;

/// An error in the library.
#[derive(Debug)]
pub enum FswError {
  /// An error from fswatch.
  FromFsw(FswStatus),
  /// An error encountered when working with C strings.
  NulError(std::ffi::NulError),
  /// An error indicating that required parameters were missing.
  MissingRequiredParameters
}

/// Status codes from fswatch.
///
/// Most operations return a status code, either `Ok` or an error. A successful operation that
/// returns `Ok` is represented by returning `Ok(T)`, where `T` is data returned, if any. If no data
/// is returned, `()` is `T`.
///
/// Errors are represented by `Err(FswStatus)`, with the status returned by the operation being
/// directly available inside the `Err`.
#[derive(Debug, PartialEq)]
pub enum FswStatus {
  /// No error.
  Ok,
  /// Occasionally used by the Rust library to denote errors without status codes in fswatch.
  UnknownError,
  SessionUnknown,
  MonitorAlreadyExists,
  Memory,
  UnknownMonitorType,
  CallbackNotSet,
  PathsNotSet,
  MissingContext,
  InvalidPath,
  InvalidCallback,
  InvalidLatency,
  InvalidRegex,
  MonitorAlreadyRunning,
  UnknownValue,
  InvalidProprety
}

impl From<ffi::FSW_STATUS> for FswStatus {
  /// Converts from the `FSW_STATUS` type into the Rust `FswStatus`.
  ///
  /// This should never need to be used if utilizing the Rust wrappers. If given an invalid code,
  /// this will default to `UnknownError`.
  fn from(status: ffi::FSW_STATUS) -> FswStatus {
    match status {
      ffi::FSW_OK => FswStatus::Ok,
      ffi::FSW_ERR_SESSION_UNKNOWN => FswStatus::SessionUnknown,
      ffi::FSW_ERR_MONITOR_ALREADY_EXISTS => FswStatus::MonitorAlreadyExists,
      ffi::FSW_ERR_MEMORY => FswStatus::Memory,
      ffi::FSW_ERR_UNKNOWN_MONITOR_TYPE => FswStatus::UnknownMonitorType,
      ffi::FSW_ERR_CALLBACK_NOT_SET => FswStatus::CallbackNotSet,
      ffi::FSW_ERR_PATHS_NOT_SET => FswStatus::PathsNotSet,
      ffi::FSW_ERR_MISSING_CONTEXT => FswStatus::MissingContext,
      ffi::FSW_ERR_INVALID_PATH => FswStatus::InvalidPath,
      ffi::FSW_ERR_INVALID_CALLBACK => FswStatus::InvalidCallback,
      ffi::FSW_ERR_INVALID_LATENCY => FswStatus::InvalidLatency,
      ffi::FSW_ERR_INVALID_REGEX => FswStatus::InvalidRegex,
      ffi::FSW_ERR_MONITOR_ALREADY_RUNNING => FswStatus::MonitorAlreadyRunning,
      ffi::FSW_ERR_UNKNOWN_VALUE => FswStatus::UnknownValue,
      ffi::FSW_ERR_INVALID_PROPERTY => FswStatus::InvalidProprety,
      ffi::FSW_ERR_UNKNOWN_ERROR | _ => FswStatus::UnknownError
    }
  }
}

/// The various possible monitors that fswatch can utilize.
#[derive(Debug, PartialEq)]
#[repr(C)]
pub enum FswMonitorType {
  SystemDefault,
  FSEvents,
  KQueue,
  INotify,
  Windows,
  Poll,
  Fen
}

/// Flags denoting the operation(s) within an event.
#[derive(Debug, PartialEq, Clone)]
#[repr(u32)]
pub enum FswEventFlag {
  NoOp = 0,
  PlatformSpecific = 1,
  Created = (1 << 1),
  Updated = (1 << 2),
  Removed = (1 << 3),
  Renamed = (1 << 4),
  OwnerModified = (1 << 5),
  AttributeModified = (1 << 6),
  MovedFrom = (1 << 7),
  MovedTo = (1 << 8),
  IsFile = (1 << 9),
  IsDir = (1 << 10),
  IsSymLink = (1 << 11),
  Link = (1 << 12),
  Overflow = (1 << 13)
}

/// A monitor filter.
#[derive(Debug)]
pub struct FswMonitorFilter {
  /// A regular expression to match paths against.
  pub text: String,
  /// The type of filter.
  pub filter_type: FswFilterType,
  /// Whether the filter should be case sensitive.
  pub case_sensitive: bool,
  pub extended: bool
}

impl FswMonitorFilter {
  pub fn new<S>(text: S, filter_type: FswFilterType, case_sensitive: bool, extended: bool) -> Self
    where S: AsRef<str>
  {
    FswMonitorFilter {
      text: text.as_ref().to_owned(),
      filter_type: filter_type,
      case_sensitive: case_sensitive,
      extended: extended
    }
  }
}

/// A filter type.
#[derive(Debug)]
#[repr(C)]
pub enum FswFilterType {
  Include,
  Exclude
}

{'fraction_non_alphanumeric': 0.12909812819058422, 'fraction_numerical': 0.007714123652864436, 'mean_word_length': 3.986425339366516, 'pattern_counts': {'":': 0, '<': 64, '<?xml version=': 0, '>': 48, 'https://': 2, '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': '4683425', 'n_tokens_mistral': 3090, 'n_tokens_neox': 3043, 'n_words': 795}