File: filepathlist.rb

package info (click to toggle)
ruby-filepath 0.7-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 244 kB
  • sloc: ruby: 1,691; makefile: 5
file content (157 lines) | stat: -rw-r--r-- 2,876 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# This is free software released into the public domain (CC0 license).


class FilepathList
	include Enumerable

	SEPARATOR = ':'.freeze

	def initialize(raw_entries = nil)
		raw_entries ||= []
		@entries = raw_entries.map { |e| e.as_path }
	end

	def select_entries(type)
		raw_entries = @entries.delete_if { |e| !e.send(type.to_s + '?') }
		return FilepathList.new(raw_entries)
	end

	def files
		return select_entries(:file)
	end

	def links
		return select_entries(:link)
	end

	def directories
		return select_entries(:directory)
	end

	def /(extra_path)
		return self.map { |path| path / extra_path }
	end

	def +(extra_entries)
		return FilepathList.new(@entries + extra_entries.to_a)
	end

	def -(others)
		remaining_entries = @entries - others.as_path_list.to_a

		return FilepathList.new(remaining_entries)
	end

	def <<(extra_path)
		return FilepathList.new(@entries + [extra_path.as_path])
	end

	def *(other_list)
		if !other_list.is_a? FilepathList
			other_list = FilepathList.new(Array(other_list))
		end
		other_entries = other_list.entries
		paths = @entries.product(other_entries).map { |p1, p2| p1 / p2 }
		return FilepathList.new(paths)
	end

	def remove_common_segments
		all_segs = @entries.map(&:segments)
		max_length = all_segs.map(&:length).min

		idx_different = nil

		(0..max_length).each do |i|
			segment = all_segs.first[i]

			different = all_segs.any? { |segs| segs[i] != segment }
			if different
				idx_different = i
				break
			end
		end

		idx_different ||= max_length

		remaining_segs = all_segs.map { |segs| segs[idx_different..-1] }

		return FilepathList.new(remaining_segs)
	end

	# @return [FilepathList] the path list itself

	def as_path_list
		self
	end

	def to_a
		@entries
	end

	def to_s
		@to_s ||= @entries.map(&:to_str).join(SEPARATOR)
	end


	# @private
	def inspect
		@entries.inspect
	end

	def ==(other)
		@entries == other.as_path_list.to_a
	end

	module ArrayMethods
		# @private
		def self.define_array_method(name)
			define_method(name) do |*args, &block|
				return @entries.send(name, *args, &block)
			end
		end

		define_array_method :[]

		define_array_method :empty?

		define_array_method :include?

		define_array_method :each

		define_array_method :all?

		define_array_method :any?

		define_array_method :none?

		define_array_method :size
	end

	module EntriesMethods
		def map(&block)
			mapped_entries = @entries.map(&block)
			return FilepathList.new(mapped_entries)
		end

		def select(pattern = nil, &block)
			if !block_given?
				block = proc { |e| e =~ pattern }
			end

			remaining_entries = @entries.select { |e| block.call(e) }

			return FilepathList.new(remaining_entries)
		end

		def exclude(pattern = nil, &block)
			if block_given?
				select { |e| !block.call(e) }
			else
				select { |e| !(e =~ pattern) }
			end
		end
	end

	include ArrayMethods
	include EntriesMethods
end