FileInfo

Struct FileInfo 

Source
pub struct FileInfo {
    pub name: String,
    pub relative_path: String,
    pub full_path: PathBuf,
    pub directory: String,
    pub depth: usize,
    pub language: Option<LanguageInfo>,
}
Expand description

Extended file information structure with metadata for intelligent matching.

This structure contains comprehensive information about discovered files, including path relationships, language detection results, and contextual metadata that enables sophisticated matching algorithms.

§Purpose

FileInfo serves as the primary data structure for file representation in the matching system. It normalizes file information from different sources and provides a consistent interface for matching algorithms.

§Path Relationships

The structure maintains three different path representations:

  • name: Just the filename for display and basic comparison
  • relative_path: Path relative to search root for organization
  • full_path: Absolute path for file system operations

§Language Detection

Language information is automatically detected from:

  • Filename patterns (e.g., “movie.en.srt”, “film.zh-tw.ass”)
  • Directory structure (e.g., “English/”, “Chinese/”)
  • File content analysis for subtitle files

§Examples

use subx_cli::core::matcher::FileInfo;
use std::path::PathBuf;

let root = PathBuf::from("/media/movies");
let file_path = PathBuf::from("/media/movies/Action/movie.en.srt");

let file_info = FileInfo::new(&file_path, &root)?;

assert_eq!(file_info.name, "movie.en.srt");
assert_eq!(file_info.relative_path, "Action/movie.en.srt");
assert_eq!(file_info.directory, "Action");
assert_eq!(file_info.depth, 1);

if let Some(lang) = &file_info.language {
    println!("Detected language: {}", lang.code);
}

Fields§

§name: String

File name without directory path for display and comparison.

This is the base filename including extension, useful for pattern matching and user-friendly display.

§relative_path: String

Path relative to the search root directory for organization.

Maintains the directory structure context while being independent of the absolute filesystem location.

§full_path: PathBuf

Absolute file system path for file operations.

Used for actual file reading, writing, and metadata access.

§directory: String

Name of the immediate parent directory containing the file.

Useful for organization-based matching and language detection from directory names.

§depth: usize

Directory depth relative to the root search path.

Indicates how many subdirectory levels deep the file is located. Depth 0 means the file is directly in the root directory.

§language: Option<LanguageInfo>

Detected language information from filename or content analysis.

Contains language code, confidence level, and detection method. May be None if no language could be reliably detected.

Implementations§

Source§

impl FileInfo

Source

pub fn new(full_path: PathBuf, root_path: &Path) -> Result<Self>

Construct a new FileInfo from a file path and search root directory.

This method performs comprehensive analysis of the file location, extracting path relationships, directory structure, and attempting automatic language detection from the filename and path.

§Arguments
  • full_path - Absolute path to the media or subtitle file
  • root_path - Root directory for file discovery (used to compute relative paths)
§Returns

Returns a FileInfo struct with all metadata populated, including optional language detection results.

§Errors

Returns SubXError::Other if:

  • The file path cannot be made relative to the root path
  • Path contains invalid Unicode characters
  • File system access issues occur during analysis
§Examples
use subx_cli::core::matcher::FileInfo;
use std::path::PathBuf;

// Simple file in root directory
let root = PathBuf::from("/media/videos");
let file_path = root.join("movie.mp4");
let info = FileInfo::new(file_path, &root)?;

assert_eq!(info.name, "movie.mp4");
assert_eq!(info.relative_path, "movie.mp4");
assert_eq!(info.depth, 0);

// File in subdirectory with language
let sub_file = root.join("English").join("movie.en.srt");
let sub_info = FileInfo::new(sub_file, &root)?;

assert_eq!(sub_info.name, "movie.en.srt");
assert_eq!(sub_info.relative_path, "English/movie.en.srt");
assert_eq!(sub_info.directory, "English");
assert_eq!(sub_info.depth, 1);
assert!(sub_info.language.is_some());
§Implementation Details
  • Path separators are normalized to Unix style (/) for consistency
  • Directory depth is calculated based on relative path components
  • Language detection runs automatically using multiple detection methods
  • All path operations are Unicode-safe with fallback to empty strings
Source

pub fn extension(&self) -> String

Get the file extension without the leading dot.

Returns the file extension in lowercase, or an empty string if no extension is present.

§Examples
assert_eq!(file_info.extension(), "mp4");
assert_eq!(subtitle_info.extension(), "srt");
Source

pub fn stem(&self) -> String

Get the filename without extension (stem).

Returns the base filename with the extension removed, useful for comparison and matching operations.

§Examples
// For "movie.en.srt"
assert_eq!(file_info.stem(), "movie.en");

// For "episode01.mp4"
assert_eq!(file_info.stem(), "episode01");
Source

pub fn is_in_root(&self) -> bool

Check if this file is in the root directory (depth 0).

Returns true if the file is directly in the search root, false if it’s in a subdirectory.

Source

pub fn has_language(&self) -> bool

Check if this file has detected language information.

Returns true if language detection was successful and confidence is above the detection threshold.

Source

pub fn language_code(&self) -> Option<&str>

Get the detected language code if available.

Returns the language code string (e.g., “en”, “zh”, “ja”) or None if no language was detected.

§Examples
if let Some(lang) = file_info.language_code() {
    println!("Detected language: {}", lang);
}
Source

pub fn normalized_name(&self) -> String

Create a normalized version of the filename for comparison.

Applies various normalization rules to make filenames more comparable during matching operations:

  • Converts to lowercase
  • Removes common separators and special characters
  • Standardizes whitespace
  • Removes quality indicators and release group tags
§Returns

A normalized filename string suitable for fuzzy matching.

§Examples
// "Movie.Name.2023.1080p.BluRay.x264-GROUP.mkv"
// becomes "movie name 2023"
let normalized = file_info.normalized_name();

Trait Implementations§

Source§

impl Clone for FileInfo

Source§

fn clone(&self) -> FileInfo

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for FileInfo

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,