Skip to content

Commit d946818

Browse files
committed
add Node.Parse/TryParse
1 parent 1a2d2e8 commit d946818

File tree

2 files changed

+95
-0
lines changed
  • src/Smdn.Fundamental.Uuid/Smdn.Formats.UniversallyUniqueIdentifiers
  • tests/Smdn.Fundamental.Uuid/Smdn.Formats.UniversallyUniqueIdentifiers

2 files changed

+95
-0
lines changed

src/Smdn.Fundamental.Uuid/Smdn.Formats.UniversallyUniqueIdentifiers/Node.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-FileCopyrightText: 2009 smdn <smdn@smdn.jp>
22
// SPDX-License-Identifier: MIT
33
using System;
4+
using System.Globalization;
45
#if SYSTEM_NET_NETWORKINFORMATION_PHYSICALADDRESS
56
using System.Net.NetworkInformation;
67
#endif
@@ -112,6 +113,45 @@ public bool TryWriteBytes(Span<byte> destination)
112113
return true;
113114
}
114115

116+
public static Node Parse(string s)
117+
=> TryParse(s ?? throw new ArgumentNullException(nameof(s)), out var result)
118+
? result
119+
: throw new FormatException("invalid format");
120+
121+
public static bool TryParse(string s, out Node result)
122+
{
123+
result = default;
124+
125+
if (s is null)
126+
return false;
127+
128+
var p =
129+
#if SYSTEM_STRING_SPLIT_CHAR
130+
s.Split(':', StringSplitOptions.None);
131+
#else
132+
s.Split(new[] { ':' }, StringSplitOptions.None);
133+
#endif
134+
135+
if (p.Length != SizeOfSelf)
136+
return false;
137+
if (!byte.TryParse(p[0], NumberStyles.HexNumber, provider: null, out var n0))
138+
return false;
139+
if (!byte.TryParse(p[1], NumberStyles.HexNumber, provider: null, out var n1))
140+
return false;
141+
if (!byte.TryParse(p[2], NumberStyles.HexNumber, provider: null, out var n2))
142+
return false;
143+
if (!byte.TryParse(p[3], NumberStyles.HexNumber, provider: null, out var n3))
144+
return false;
145+
if (!byte.TryParse(p[4], NumberStyles.HexNumber, provider: null, out var n4))
146+
return false;
147+
if (!byte.TryParse(p[5], NumberStyles.HexNumber, provider: null, out var n5))
148+
return false;
149+
150+
result = new(n0, n1, n2, n3, n4, n5);
151+
152+
return true;
153+
}
154+
115155
public override string ToString() => ToString(format: null, formatProvider: null);
116156

117157
public string ToString(string format, IFormatProvider formatProvider = null)

tests/Smdn.Fundamental.Uuid/Smdn.Formats.UniversallyUniqueIdentifiers/Node.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,61 @@ public void TryWriteBytes_DestinationLengthTooShort()
8383
Assert.IsFalse(node.TryWriteBytes(stackalloc byte[0]), "length 0");
8484
}
8585

86+
[Test]
87+
public void TestParse_ArgumentNull() => Assert.Throws<ArgumentNullException>(() => Node.Parse(null));
88+
89+
[TestCase("00:00:00:00:00:00", true, "00:00:00:00:00:00")]
90+
[TestCase("01:23:45:67:89:AB", true, "01:23:45:67:89:AB")]
91+
[TestCase("FF:FF:FF:FF:FF:FF", true, "FF:FF:FF:FF:FF:FF")]
92+
[TestCase("ab:cd:ef:AB:CD:EF", true, "ab:cd:ef:AB:CD:EF")]
93+
[TestCase("0:1:2:3:4:F", true, "00:01:02:03:04:0F")]
94+
[TestCase("000:001:002:003:004:00F", true, "00:01:02:03:04:0F")]
95+
[TestCase("00:00:00:00:00", false, null)]
96+
[TestCase("00", false, null)]
97+
[TestCase("", false, null)]
98+
[TestCase("100:00:00:00:00:00", false, null)]
99+
[TestCase("00:00:00:00:00:100", false, null)]
100+
[TestCase("00:00:00:00:00:0X", false, null)]
101+
[TestCase("00-00-00-00-00-00", false, null)]
102+
public void TestParse(string s, bool expectValid, string expectedString)
103+
{
104+
Node n = default;
105+
106+
if (expectValid)
107+
Assert.DoesNotThrow(() => n = Node.Parse(s));
108+
else
109+
Assert.Throws<FormatException>(() => n = Node.Parse(s));
110+
111+
if (expectValid) {
112+
Assert.AreEqual(expectedString.ToUpperInvariant(), n.ToString("X"));
113+
Assert.AreEqual(expectedString.ToLowerInvariant(), n.ToString("x"));
114+
}
115+
}
116+
117+
[TestCase("00:00:00:00:00:00", true, "00:00:00:00:00:00")]
118+
[TestCase("01:23:45:67:89:AB", true, "01:23:45:67:89:AB")]
119+
[TestCase("FF:FF:FF:FF:FF:FF", true, "FF:FF:FF:FF:FF:FF")]
120+
[TestCase("ab:cd:ef:AB:CD:EF", true, "ab:cd:ef:AB:CD:EF")]
121+
[TestCase("0:1:2:3:4:F", true, "00:01:02:03:04:0F")]
122+
[TestCase("000:001:002:003:004:00F", true, "00:01:02:03:04:0F")]
123+
[TestCase("00:00:00:00:00", false, null)]
124+
[TestCase("00", false, null)]
125+
[TestCase("", false, null)]
126+
[TestCase(null, false, null)]
127+
[TestCase("100:00:00:00:00:00", false, null)]
128+
[TestCase("00:00:00:00:00:100", false, null)]
129+
[TestCase("00:00:00:00:00:0X", false, null)]
130+
[TestCase("00-00-00-00-00-00", false, null)]
131+
public void TestTryParse(string s, bool expectValid, string expectedString)
132+
{
133+
Assert.AreEqual(expectValid, Node.TryParse(s, out var node));
134+
135+
if (expectValid) {
136+
Assert.AreEqual(expectedString.ToUpperInvariant(), node.ToString("X"));
137+
Assert.AreEqual(expectedString.ToLowerInvariant(), node.ToString("x"));
138+
}
139+
}
140+
86141
[Test]
87142
public void TestToString()
88143
{

0 commit comments

Comments
 (0)