• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

neon-sunset / U8String / 6005208900

28 Aug 2023 09:36PM UTC coverage: 18.096% (-0.2%) from 18.326%
6005208900

push

github

neon-sunset
feat: Extend NativeU8String and restructure solution to account for increased line count, add roadmap draft

134 of 1050 branches covered (0.0%)

Branch coverage included in aggregate %.

1058 of 1058 new or added lines in 25 files covered. (100.0%)

478 of 2332 relevant lines covered (20.5%)

35305.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.86
/src/Implementations/Standard/U8String.Construction.cs
1
using System.Collections.Immutable;
2
using System.Diagnostics;
3
using System.Diagnostics.CodeAnalysis;
4
using System.Runtime.InteropServices;
5
using U8Primitives.InteropServices;
6

7
namespace U8Primitives;
8

9
public readonly partial struct U8String
10
{
11
    /// <summary>
12
    /// Creates a new <see cref="U8String"/> from the specified UTF-8 bytes.
13
    /// </summary>
14
    /// <param name="value">The UTF-8 bytes to create the <see cref="U8String"/> from.</param>
15
    /// <exception cref="ArgumentException">Thrown when <paramref name="value"/> contains malformed UTF-8 data.</exception>
16
    /// <remarks>
17
    /// The <see cref="U8String"/> will be created by copying the <paramref name="value"/> bytes if the length is greater than 0.
18
    /// </remarks>
19
    public U8String(ReadOnlySpan<byte> value)
20
    {
21
        // Contract:
22
        // byte[] Value *must* remain null if the length is 0.
23
        if (value.Length > 0)
54✔
24
        {
25
            Validate(value);
45✔
26
            _value = value.ToArray();
45✔
27
            _inner = new U8Range(0, value.Length);
45✔
28
        }
29
    }
54✔
30

31
    /// <summary>
32
    /// Creates a new <see cref="U8String"/> from the specified <see cref="ImmutableArray{T}"/> of <see cref="byte"/>s.
33
    /// </summary>
34
    /// <param name="value">The <see cref="ImmutableArray{T}"/> of <see cref="byte"/>s to create the <see cref="U8String"/> from.</param>
35
    /// <exception cref="ArgumentException">Thrown when <paramref name="value"/> contains malformed UTF-8 data.</exception>
36
    /// <remarks>
37
    /// The <see cref="U8String"/> will be created by taking the underlying reference from the <paramref name="value"/> without copying if the length is greater than 0.
38
    /// </remarks>
39
    public U8String(ImmutableArray<byte> value)
40
    {
41
        var bytes = ImmutableCollectionsMarshal.AsArray(value);
×
42
        if (bytes?.Length > 0)
×
43
        {
44
            Validate(bytes);
×
45
            _value = bytes;
×
46
            _inner = new U8Range(0, bytes.Length);
×
47
        }
48
    }
×
49

50
    /// <summary>
51
    /// Creates a new <see cref="U8String"/> from the specified <see cref="ReadOnlySpan{T}"/> of UTF-8 <see cref="char"/>s.
52
    /// </summary>
53
    /// <param name="value">The <see cref="ReadOnlySpan{T}"/> of <see cref="char"/>s to create the <see cref="U8String"/> from.</param>
54
    /// <remarks>
55
    /// The <see cref="U8String"/> will be created by encoding the <see cref="char"/>s as UTF-8.
56
    /// </remarks>
57
    public U8String(ReadOnlySpan<char> value)
58
    {
59
        if (value.Length > 0)
×
60
        {
61
            this = Parse(value, null);
×
62
        }
63
    }
×
64

65
    /// <summary>
66
    /// Creates a new <see cref="U8String"/> from the specified <see cref="string"/>.
67
    /// </summary>
68
    /// <param name="value">The <see cref="string"/> to create the <see cref="U8String"/> from.</param>
69
    /// <remarks>
70
    /// The <see cref="U8String"/> will be created by encoding the <see cref="string"/> as UTF-8.
71
    /// </remarks>
72
    public U8String(string? value)
73
    {
74
        if (!string.IsNullOrEmpty(value))
×
75
        {
76
            this = Parse(value.AsSpan(), null);
×
77
        }
78
    }
×
79

80
    /// <summary>
81
    /// Direct constructor of <see cref="U8String"/> from a <see cref="byte"/> array.
82
    /// </summary>
83
    /// <remarks>
84
    /// Contract:
85
    /// The constructor will *always* drop the reference if the length is 0.
86
    /// Consequently, the value *must* remain null if the length is 0.
87
    /// </remarks>
88
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
89
    internal U8String(byte[]? value, int offset, int length)
90
    {
91
        if (length > 0) _value = value;
×
92
        _inner = new U8Range(offset, length);
×
93

94
        Debug.Assert(Offset >= 0);
95
        Debug.Assert(_value is null ? Length is 0 : (uint)Length > 0);
96
    }
×
97

98
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
99
    internal U8String(byte[]? value, U8Range inner)
100
    {
101
        if (inner.Length > 0) _value = value;
×
102
        _inner = inner;
×
103

104
        Debug.Assert(Offset >= 0);
105
        Debug.Assert(_value is null ? Length is 0 : (uint)Length > 0);
106
    }
×
107

108
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
109
    internal U8String(ReadOnlySpan<byte> value, bool skipValidation)
110
    {
111
        Debug.Assert(skipValidation);
112

113
        if (value.Length > 0) _value = value.ToArray();
×
114
        _inner = new U8Range(0, value.Length);
×
115

116
        Debug.Assert(Offset >= 0);
117
        Debug.Assert(_value is null ? Length is 0 : (uint)Length > 0);
118
    }
×
119

120
    /// <inheritdoc cref="U8String(ReadOnlySpan{byte})"/>
121
    // Tracks https://github.com/dotnet/runtime/issues/87569
122
    public static U8String Create(/*params*/ ReadOnlySpan<byte> value) => new(value);
×
123

124
    /// <inheritdoc cref="U8String(ImmutableArray{byte})"/>
125
    public static U8String Create(ImmutableArray<byte> value) => new(value);
×
126

127
    /// <inheritdoc cref="U8String(string)"/>
128
    public static U8String Create(string value) => new(value);
×
129

130
    /// <inheritdoc cref="U8String(ReadOnlySpan{char})"/>
131
    public static U8String Create(/*params*/ ReadOnlySpan<char> value) => new(value);
×
132

133
    /// <inheritdoc cref="U8StringExtensions.ToU8String{T}(T)"/>
134
    public static U8String Create<T>(T value)
135
        where T : IUtf8SpanFormattable
136
    {
137
        // TODO: Invert where the implementation lives?
138
        return value.ToU8String();
×
139
    }
140

141
    /// <inheritdoc cref="U8StringExtensions.ToU8String{T}(T, ReadOnlySpan{char})"/>
142
    public static U8String Create<T>(T value, ReadOnlySpan<char> format)
143
        where T : IUtf8SpanFormattable
144
    {
145
        return value.ToU8String(format);
×
146
    }
147

148
    /// <inheritdoc cref="U8StringExtensions.ToU8String{T}(T, IFormatProvider?)"/>
149
    public static U8String Create<T>(T value, IFormatProvider? provider)
150
        where T : IUtf8SpanFormattable
151
    {
152
        return value.ToU8String(provider);
×
153
    }
154

155
    /// <inheritdoc cref="U8StringExtensions.ToU8String{T}(T, ReadOnlySpan{char}, IFormatProvider?)"/>
156
    public static U8String Create<T>(T value, ReadOnlySpan<char> format, IFormatProvider? provider)
157
        where T : IUtf8SpanFormattable
158
    {
159
        return value.ToU8String(format, provider);
×
160
    }
161

162
    /// <summary>
163
    /// Creates a new <see cref="U8String"/> from <paramref name="value"/> without verifying
164
    /// if it is a valid UTF-8 sequence.
165
    /// </summary>
166
    /// <param name="value">The UTF-8 bytes to create the <see cref="U8String"/> from.</param>
167
    /// <remarks>
168
    /// The <see cref="U8String"/> will be created by copying the <paramref name="value"/> bytes if the length is greater than 0.
169
    /// </remarks>
170
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
171
    public static U8String CreateUnchecked(ReadOnlySpan<byte> value)
172
    {
173
        return new(value, skipValidation: true);
×
174
    }
175

176
    /// <summary>
177
    /// Creates a new <see cref="U8String"/> from <paramref name="value"/> without verifying
178
    /// if it is a valid UTF-8 sequence.
179
    /// </summary>
180
    /// <param name="value">The UTF-8 bytes to create the <see cref="U8String"/> from.</param>
181
    /// <remarks>
182
    /// <para>
183
    /// The <see cref="U8String"/> will be created by taking the underlying reference from the
184
    /// <paramref name="value"/> without copying if the length is greater than 0.
185
    /// </para>
186
    /// <para>
187
    /// This is a safe variant of <see cref="U8Marshal.Create(byte[])"/> which does not allocate.
188
    /// </para>
189
    /// </remarks>
190
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
191
    public static U8String CreateUnchecked(ImmutableArray<byte> value)
192
    {
193
        var bytes = ImmutableCollectionsMarshal.AsArray(value);
×
194
        if (bytes != null)
×
195
        {
196
            return new(bytes, 0, bytes.Length);
×
197
        }
198

199
        return default;
×
200
    }
201

202
    public static U8String Move([MaybeNull] ref byte[]? value)
203
    {
204
        var source = value;
×
205
        value = null;
×
206
        var result = default(U8String);
×
207

208
        if (source?.Length > 0)
×
209
        {
210
            Validate(source);
×
211
            result = new U8String(source, 0, source.Length);
×
212
        }
213

214
        return result;
×
215
    }
216

217
    public static U8String Move([MaybeNull] ref byte[]? value, int offset, int length)
218
    {
219
        var source = value;
×
220
        value = null;
×
221
        var result = default(U8String);
×
222

223
        if (source != null)
×
224
        {
225
            Validate(source.AsSpan().Slice(offset, length));
×
226
            result = new U8String(source, offset, length);
×
227
        }
228

229
        return result;
×
230
    }
231

232
    /// <summary>
233
    /// Clones the <see cref="U8String"/> by copying the underlying
234
    /// <see cref="Length"/> of bytes into a new <see cref="U8String"/> instance.
235
    /// </summary>
236
    /// <remarks>
237
    /// <para>
238
    /// This method is useful when a particular <see cref="U8String"/> is a slice of a larger
239
    /// <see cref="U8String"/> that is no longer needed and can be garbage collected.
240
    /// This allows the GC to collect the larger <see cref="U8String"/> and reclaim the memory
241
    /// it would hold otherwise.
242
    /// </para>
243
    /// <para>
244
    /// Example:
245
    /// <code>
246
    /// var articleText = await httpClient.GetU8StringAsync("https://example.com/article.txt");
247
    /// var previewText = articleText[..100].Clone();
248
    /// </code>
249
    /// </para>
250
    /// </remarks>
251
    public U8String Clone() => new(this, skipValidation: true);
×
252

253
    /// <inheritdoc />
254
    object ICloneable.Clone() => Clone();
×
255
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc