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

neon-sunset / U8String / 5872750434

pending completion
5872750434

push

github

neon-sunset
feat: U8SplitOptions.Trim impl. on Split

105 of 742 branches covered (14.15%)

Branch coverage included in aggregate %.

4 of 4 new or added lines in 2 files covered. (100.0%)

372 of 1600 relevant lines covered (23.25%)

444.8 hits per line

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

12.28
/src/U8String.Construction.cs
1
using System.Collections.Immutable;
2
using System.Diagnostics;
3
using System.Runtime.InteropServices;
4
using U8Primitives.InteropServices;
5

6
namespace U8Primitives;
7

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

30
    /// <summary>
31
    /// Creates a new <see cref="U8String"/> from the specified <see cref="ImmutableArray{T}"/> of <see cref="byte"/>s.
32
    /// </summary>
33
    /// <param name="value">The <see cref="ImmutableArray{T}"/> of <see cref="byte"/>s to create the <see cref="U8String"/> from.</param>
34
    /// <exception cref="ArgumentException">Thrown when <paramref name="value"/> contains malformed UTF-8 data.</exception>
35
    /// <remarks>
36
    /// 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.
37
    /// </remarks>
38
    public U8String(ImmutableArray<byte> value)
39
    {
40
        var bytes = ImmutableCollectionsMarshal.AsArray(value);
×
41
        if (bytes?.Length > 0)
×
42
        {
43
            Validate(bytes);
×
44
            _value = bytes;
×
45
            _inner = new U8Range(0, bytes.Length);
×
46
        }
47
    }
×
48

49
    /// <summary>
50
    /// Creates a new <see cref="U8String"/> from the specified <see cref="ReadOnlySpan{T}"/> of UTF-8 <see cref="char"/>s.
51
    /// </summary>
52
    /// <param name="value">The <see cref="ReadOnlySpan{T}"/> of <see cref="char"/>s to create the <see cref="U8String"/> from.</param>
53
    /// <remarks>
54
    /// The <see cref="U8String"/> will be created by encoding the <see cref="char"/>s as UTF-8.
55
    /// </remarks>
56
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
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
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
73
    public U8String(string? value)
74
    {
75
        if (!string.IsNullOrEmpty(value))
×
76
        {
77
            this = Parse(value.AsSpan(), null);
×
78
        }
79
    }
×
80

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

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

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

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

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

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

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

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

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

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

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

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

142
    /// <inheritdoc cref="U8StringExtensions.ToU8String{T}(T, IFormatProvider?)"/>
143
    public static U8String Create<T>(T value, IFormatProvider? provider = null)
144
        where T : IUtf8SpanFormattable
145
    {
146
        return value.ToU8String(provider);
×
147
    }
148

149
    /// <summary>
150
    /// Creates a new <see cref="U8String"/> from <paramref name="value"/> without validating
151
    /// if it is a valid UTF-8 sequence.
152
    /// </summary>
153
    /// <param name="value">The UTF-8 bytes to create the <see cref="U8String"/> from.</param>
154
    /// <remarks>
155
    /// The <see cref="U8String"/> will be created by copying the <paramref name="value"/> bytes if the length is greater than 0.
156
    /// </remarks>
157
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
158
    public static U8String CreateUnchecked(ReadOnlySpan<byte> value)
159
    {
160
        return new(value, skipValidation: true);
×
161
    }
162

163
    /// <summary>
164
    /// Creates a new <see cref="U8String"/> from <paramref name="value"/> without validating
165
    /// if it is a valid UTF-8 sequence.
166
    /// </summary>
167
    /// <param name="value">The UTF-8 bytes to create the <see cref="U8String"/> from.</param>
168
    /// <remarks>
169
    /// <para>
170
    /// The <see cref="U8String"/> will be created by taking the underlying reference from the
171
    /// <paramref name="value"/> without copying if the length is greater than 0.
172
    /// </para>
173
    /// <para>
174
    /// This is a safe variant of <see cref="U8Marshal.Create(byte[])"/> which does not allocate.
175
    /// </para>
176
    /// </remarks>
177
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
178
    public static U8String CreateUnchecked(ImmutableArray<byte> value)
179
    {
180
        var bytes = ImmutableCollectionsMarshal.AsArray(value);
×
181
        if (bytes != null)
×
182
        {
183
            return new(bytes, 0, bytes.Length);
×
184
        }
185

186
        return default;
×
187
    }
188

189
    /// <summary>
190
    /// Clones the <see cref="U8String"/> by copying the underlying
191
    /// <see cref="Length"/> of bytes into a new <see cref="U8String"/> instance.
192
    /// </summary>
193
    /// <remarks>
194
    /// <para>
195
    /// This method is useful when a particular <see cref="U8String"/> is a slice of a larger
196
    /// <see cref="U8String"/> that is no longer needed and can be garbage collected.
197
    /// This allows the GC to collect the larger <see cref="U8String"/> and reclaim the memory
198
    /// it would hold otherwise.
199
    /// </para>
200
    /// <para>
201
    /// Example:
202
    /// <code>
203
    /// var articleText = await httpClient.GetU8StringAsync("https://example.com/article.txt");
204
    /// var previewText = articleText[..100].Clone();
205
    /// </code>
206
    /// </para>
207
    /// </remarks>
208
    public U8String Clone() => new(this, skipValidation: true);
×
209

210
    /// <inheritdoc />
211
    object ICloneable.Clone() => Clone();
×
212
}
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