Class: Ace::Support::Items::Atoms::SpecialFolderDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/items/atoms/special_folder_detector.rb

Overview

Detects and normalizes “special” folder names used for item organization. Special folders use a configurable prefix convention (default: “_”). Short names (without prefix) are auto-expanded: “archive” => “_archive”.

Constant Summary collapse

DEFAULT_PREFIX =

Default prefix for special folders (single source of truth)

"_"
VIRTUAL_FILTERS =

Virtual filters — not physical folders, used for list filtering

{"next" => :next, "all" => :all}.freeze
MOVE_TO_ROOT_ALIASES =

Aliases that mean “move back to root” (no special folder). “next” is the primary label; “root” and “/” are convenience aliases.

%w[next root /].freeze

Class Method Summary collapse

Class Method Details

.detect_in_path(path, root: nil, prefix: DEFAULT_PREFIX) ⇒ String?

Extract the special folder from a path (if any) Returns the first path component that is a special folder

Parameters:

  • path (String)

    File path to inspect

  • root (String) (defaults to: nil)

    Root path to make path relative

  • prefix (String) (defaults to: DEFAULT_PREFIX)

    The prefix that marks special folders

Returns:

  • (String, nil)

    Special folder name or nil



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/ace/support/items/atoms/special_folder_detector.rb', line 83

def self.detect_in_path(path, root: nil, prefix: DEFAULT_PREFIX)
  check_path = if root
    begin
      Pathname.new(path).relative_path_from(Pathname.new(root)).to_s
    rescue ArgumentError
      path
    end
  else
    path
  end

  parts = check_path.split(File::SEPARATOR).reject(&:empty?)
  parts.find { |part| special?(part, prefix: prefix) }
end

.move_to_root?(name) ⇒ Boolean

Check if a name means “move to root” (out of any special folder).

Parameters:

  • name (String)

    The name to check

Returns:

  • (Boolean)

    True if the name is a move-to-root alias



26
27
28
29
30
# File 'lib/ace/support/items/atoms/special_folder_detector.rb', line 26

def self.move_to_root?(name)
  return false if name.nil? || name.empty?

  MOVE_TO_ROOT_ALIASES.include?(name.downcase)
end

.normalize(folder_name, prefix: DEFAULT_PREFIX) ⇒ String

Normalize a folder name to its canonical form Short names are expanded: “archive” => “_archive” Already-prefixed names are returned as-is Virtual filters are returned as-is (not expanded)

Parameters:

  • folder_name (String)

    The folder name to normalize

  • prefix (String) (defaults to: DEFAULT_PREFIX)

    The prefix to prepend for expansion

Returns:

  • (String)

    Canonical folder name



58
59
60
61
62
63
64
65
# File 'lib/ace/support/items/atoms/special_folder_detector.rb', line 58

def self.normalize(folder_name, prefix: DEFAULT_PREFIX)
  return folder_name if folder_name.nil? || folder_name.empty?
  return folder_name if folder_name.start_with?(prefix)
  return folder_name if VIRTUAL_FILTERS.key?(folder_name.downcase)
  return folder_name if folder_name.include?(File::SEPARATOR) || folder_name.include?("..")

  "#{prefix}#{folder_name}"
end

.short_name(folder_name, prefix: DEFAULT_PREFIX) ⇒ String

Strip the special folder prefix to get the short display name

Parameters:

  • folder_name (String)

    The folder name (e.g. “_archive”)

  • prefix (String) (defaults to: DEFAULT_PREFIX)

    The prefix to strip

Returns:

  • (String)

    Short name (e.g. “archive”)



71
72
73
74
75
# File 'lib/ace/support/items/atoms/special_folder_detector.rb', line 71

def self.short_name(folder_name, prefix: DEFAULT_PREFIX)
  return folder_name if folder_name.nil? || folder_name.empty?

  folder_name.delete_prefix(prefix)
end

.special?(folder_name, prefix: DEFAULT_PREFIX) ⇒ Boolean

Detect if a folder name is a special folder

Parameters:

  • folder_name (String)

    The folder name to check

  • prefix (String) (defaults to: DEFAULT_PREFIX)

    The prefix that marks special folders

Returns:

  • (Boolean)

    True if it’s a special folder



45
46
47
48
49
# File 'lib/ace/support/items/atoms/special_folder_detector.rb', line 45

def self.special?(folder_name, prefix: DEFAULT_PREFIX)
  return false if folder_name.nil? || folder_name.empty?

  folder_name.start_with?(prefix)
end

.virtual_filter?(name) ⇒ Symbol?

Check if a name is a virtual filter

Parameters:

  • name (String)

    The name to check

Returns:

  • (Symbol, nil)

    :next, :all, or nil



35
36
37
38
39
# File 'lib/ace/support/items/atoms/special_folder_detector.rb', line 35

def self.virtual_filter?(name)
  return nil if name.nil? || name.empty?

  VIRTUAL_FILTERS[name.downcase]
end