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

neon-sunset / U8String / 5903348006

18 Aug 2023 01:41PM UTC coverage: 21.619% (-0.03%) from 21.646%
5903348006

push

github

neon-sunset
feat: better conversion overloads

115 of 776 branches covered (14.82%)

Branch coverage included in aggregate %.

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

411 of 1657 relevant lines covered (24.8%)

17208.32 hits per line

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

11.86
/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, ReadOnlySpan{char})"/>
143
    public static U8String Create<T>(T value, ReadOnlySpan<char> format)
144
        where T : IUtf8SpanFormattable
145
    {
146
        return value.ToU8String(format);
×
147
    }
148

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

156
    /// <inheritdoc cref="U8StringExtensions.ToU8String{T}(T, ReadOnlySpan{char}, IFormatProvider?)"/>
157
    public static U8String Create<T>(T value, ReadOnlySpan<char> format, IFormatProvider? provider)
158
        where T : IUtf8SpanFormattable
159
    {
160
        return value.ToU8String(format, provider);
×
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
    /// The <see cref="U8String"/> will be created by copying the <paramref name="value"/> bytes if the length is greater than 0.
170
    /// </remarks>
171
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
172
    public static U8String CreateUnchecked(ReadOnlySpan<byte> value)
173
    {
174
        return new(value, skipValidation: true);
×
175
    }
176

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

200
        return default;
×
201
    }
202

203
    /// <summary>
204
    /// Clones the <see cref="U8String"/> by copying the underlying
205
    /// <see cref="Length"/> of bytes into a new <see cref="U8String"/> instance.
206
    /// </summary>
207
    /// <remarks>
208
    /// <para>
209
    /// This method is useful when a particular <see cref="U8String"/> is a slice of a larger
210
    /// <see cref="U8String"/> that is no longer needed and can be garbage collected.
211
    /// This allows the GC to collect the larger <see cref="U8String"/> and reclaim the memory
212
    /// it would hold otherwise.
213
    /// </para>
214
    /// <para>
215
    /// Example:
216
    /// <code>
217
    /// var articleText = await httpClient.GetU8StringAsync("https://example.com/article.txt");
218
    /// var previewText = articleText[..100].Clone();
219
    /// </code>
220
    /// </para>
221
    /// </remarks>
222
    public U8String Clone() => new(this, skipValidation: true);
×
223

224
    /// <inheritdoc />
225
    object ICloneable.Clone() => Clone();
×
226
}
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

© 2025 Coveralls, Inc