-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathResourcePath.cs
More file actions
151 lines (112 loc) · 4.15 KB
/
Copy pathResourcePath.cs
File metadata and controls
151 lines (112 loc) · 4.15 KB
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
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using DataBoss.IO;
using Newtonsoft.Json;
namespace DataBoss.DataPackage
{
[JsonConverter(typeof(ItemOrArrayJsonConverter))]
public struct ResourcePath : IEquatable<ResourcePath>, ICollection<string>
{
interface IResourcePathState : IEnumerable<string>
{
int Count { get; }
void Add(string path, out IResourcePathState next);
}
class EmptyPath : IResourcePathState
{
public int Count => 0;
EmptyPath() { }
public void Add(string path, out IResourcePathState next) =>
next = new SinglePath(path);
public IEnumerator<string> GetEnumerator() =>
Enumerable.Empty<string>().GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
public static readonly EmptyPath Instance = new();
public override string ToString() => string.Empty;
public override int GetHashCode() => 0;
}
class SinglePath : IResourcePathState
{
public readonly string Path;
public SinglePath(string path) { this.Path = path; }
public int Count => 1;
public void Add(string path, out IResourcePathState next) =>
next = new MultiPath(ImmutableList<string>.Empty.AddRange(new[] { Path, path }));
public override string ToString() => Path;
public override int GetHashCode() => Path.GetHashCode();
public IEnumerator<string> GetEnumerator() {
yield return Path;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
class MultiPath : IResourcePathState
{
readonly ImmutableList<string> paths;
public int Count => paths.Count;
public MultiPath(ImmutableList<string> paths) {
this.paths = paths;
}
public void Add(string path, out IResourcePathState next) =>
next = new MultiPath(paths.Add(path));
public IEnumerator<string> GetEnumerator() => paths.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public override string ToString() => string.Join(",", paths);
public override int GetHashCode() =>
Count == 0 ? 0 : paths[0].GetHashCode();
}
IResourcePathState state;
IResourcePathState CurrentState => state ??= EmptyPath.Instance;
public bool IsEmpty => Count == 0;
public int Count => CurrentState.Count;
public bool IsReadOnly => false;
ResourcePath(IResourcePathState state) {
this.state = state;
}
public bool TryGetOutputPath(out string outputPath) {
if (Count != 1) {
outputPath = null;
return false;
}
outputPath = this.First();
return true;
}
public override bool Equals(object obj) =>
obj is ResourcePath other && Equals(other);
public override string ToString() =>
CurrentState.ToString();
public override int GetHashCode() =>
CurrentState.GetHashCode();
public bool Equals(ResourcePath other) =>
ReferenceEquals(this.state, other.state) || other.SequenceEqual(this);
public void Add(string item) =>
CurrentState.Add(item, out state);
public void Clear() {
state = EmptyPath.Instance;
}
public bool Contains(string item) {
using var items = GetEnumerator();
while (items.MoveNext())
if (items.Current == item)
return true;
return false;
}
public void CopyTo(string[] array, int arrayIndex) {
throw new NotImplementedException();
}
public bool Remove(string item) {
throw new NotImplementedException();
}
public IEnumerator<string> GetEnumerator() => CurrentState.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public static implicit operator ResourcePath(string path) => new(new SinglePath(path));
public static implicit operator ResourcePath(string[] path) => new(new MultiPath(ImmutableList<string>.Empty.AddRange(path)));
public static implicit operator string(ResourcePath path) => path.ToString();
public static bool operator ==(ResourcePath left, string path) => left.ToString() == path;
public static bool operator !=(ResourcePath left, string path) => left.ToString() != path;
}
}