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

icerpc / icerpc-csharp / 20870171951

10 Jan 2026 01:03AM UTC coverage: 83.304% (-0.1%) from 83.399%
20870171951

Pull #4221

github

web-flow
Merge fe4f556d8 into f39e9819d
Pull Request #4221: Use new C#14 extension block syntax

12030 of 14441 relevant lines covered (83.3%)

2957.05 hits per line

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

83.16
src/ZeroC.Slice/SliceEncoderExtensions.cs
1
// Copyright (c) ZeroC, Inc.
2

3
using System.Buffers;
4
using System.Collections.Immutable;
5
using System.Diagnostics;
6
using System.Runtime.InteropServices;
7

8
namespace ZeroC.Slice;
9

10
/// <summary>Provides extension methods for <see cref="SliceEncoder" /> to encode sequences or dictionaries.</summary>
11
public static class SliceEncoderExtensions
12
{
13
    /// <summary>Extension methods for <see cref="SliceEncoder" />.</summary>
14
    /// <param name="encoder">The Slice encoder.</param>
15
    extension(ref SliceEncoder encoder)
16
    {
17
        /// <summary>Encodes a dictionary.</summary>
18
        /// <typeparam name="TKey">The dictionary key type.</typeparam>
19
        /// <typeparam name="TValue">The dictionary value type.</typeparam>
20
        /// <param name="v">The dictionary to encode.</param>
21
        /// <param name="keyEncodeAction">The encode action for the keys.</param>
22
        /// <param name="valueEncodeAction">The encode action for the values.</param>
23
        public void EncodeDictionary<TKey, TValue>(
24
            IEnumerable<KeyValuePair<TKey, TValue>> v,
25
            EncodeAction<TKey> keyEncodeAction,
26
            EncodeAction<TValue> valueEncodeAction)
27
            where TKey : notnull
28
        {
2,854✔
29
            encoder.EncodeSize(v.Count());
2,854✔
30
            foreach ((TKey key, TValue value) in v)
15,233✔
31
            {
3,336✔
32
                keyEncodeAction(ref encoder, key);
3,336✔
33
                valueEncodeAction(ref encoder, value);
3,336✔
34
            }
3,335✔
35
        }
2,853✔
36

37
        /// <summary>Encodes a dictionary with an optional value type (T? in Slice).</summary>
38
        /// <typeparam name="TKey">The dictionary key type.</typeparam>
39
        /// <typeparam name="TValue">The dictionary value type.</typeparam>
40
        /// <param name="v">The dictionary to encode.</param>
41
        /// <param name="keyEncodeAction">The encode action for the keys.</param>
42
        /// <param name="valueEncodeAction">The encode action for the non-null values.</param>
43
        public void EncodeDictionaryWithOptionalValueType<TKey, TValue>(
44
            IEnumerable<KeyValuePair<TKey, TValue>> v,
45
            EncodeAction<TKey> keyEncodeAction,
46
            EncodeAction<TValue> valueEncodeAction)
47
            where TKey : notnull
48
        {
14✔
49
            int count = v.Count();
14✔
50
            encoder.EncodeSize(count);
14✔
51
            if (count > 0)
14✔
52
            {
14✔
53
                foreach ((TKey key, TValue value) in v)
122✔
54
                {
40✔
55
                    // Each entry is encoded like a:
56
                    // compact struct Pair
57
                    // {
58
                    //     key: Key,
59
                    //     value: Value?
60
                    // }
61
                    encoder.EncodeBool(value is not null); // simplified bit sequence
40✔
62

63
                    keyEncodeAction(ref encoder, key);
40✔
64
                    if (value is not null)
40✔
65
                    {
26✔
66
                        valueEncodeAction(ref encoder, value);
26✔
67
                    }
26✔
68
                }
40✔
69
            }
14✔
70
        }
14✔
71

72
        /// <summary>Encodes a result.</summary>
73
        /// <typeparam name="TSuccess">The type of the success value.</typeparam>
74
        /// <typeparam name="TFailure">The type of the failure value.</typeparam>
75
        /// <param name="v">The result to encode.</param>
76
        /// <param name="successEncodeAction">The encode action for the success type.</param>
77
        /// <param name="failureEncodeAction">The encode action for the failure type.</param>
78
        public void EncodeResult<TSuccess, TFailure>(
79
            Result<TSuccess, TFailure> v,
80
            EncodeAction<TSuccess> successEncodeAction,
81
            EncodeAction<TFailure> failureEncodeAction)
82
        {
4✔
83
            switch (v)
4✔
84
            {
85
                case Result<TSuccess, TFailure>.Success success:
86
                    encoder.EncodeVarInt32(0);
2✔
87
                    successEncodeAction(ref encoder, success.Value);
2✔
88
                    break;
2✔
89

90
                case Result<TSuccess, TFailure>.Failure failure:
91
                    encoder.EncodeVarInt32(1);
2✔
92
                    failureEncodeAction(ref encoder, failure.Value);
2✔
93
                    break;
2✔
94

95
                default:
96
                    // Our result type somehow got extended with an additional enumerator.
97
                    Debug.Fail("Unexpected result type");
×
98
                    break;
×
99
            }
100
        }
4✔
101

102
        /// <summary>Encodes a sequence of fixed-size numeric values, such as int or ulong.</summary>
103
        /// <typeparam name="T">The sequence element type.</typeparam>
104
        /// <param name="v">The sequence of numeric values.</param>
105
        public void EncodeSequence<T>(IEnumerable<T> v)
106
            where T : struct
107
        {
3,232✔
108
            switch (v)
3,232✔
109
            {
110
                case T[] vArray:
111
                    encoder.EncodeSpan(new ReadOnlySpan<T>(vArray));
3,231✔
112
                    break;
3,231✔
113

114
                case ImmutableArray<T> vImmutableArray:
115
                    encoder.EncodeSpan(vImmutableArray.AsSpan());
×
116
                    break;
×
117

118
                case ArraySegment<T> vArraySegment:
119
                    encoder.EncodeSpan((ReadOnlySpan<T>)vArraySegment.AsSpan());
×
120
                    break;
×
121

122
                case List<T> list:
123
                    encoder.EncodeSpan((ReadOnlySpan<T>)CollectionsMarshal.AsSpan(list));
1✔
124
                    break;
1✔
125

126
                default:
127
                    encoder.EncodeSequence(
×
128
                        v,
×
129
                        (ref SliceEncoder encoder, T element) => encoder.EncodeFixedSizeNumeric(element));
×
130
                    break;
×
131
            }
132
        }
3,232✔
133

134
        /// <summary>Encodes a sequence.</summary>
135
        /// <typeparam name="T">The type of the sequence elements. It is non-nullable except for nullable class
136
        /// and nullable custom types with Slice1.</typeparam>
137
        /// <param name="v">The sequence to encode.</param>
138
        /// <param name="encodeAction">The encode action for an element.</param>
139
        public void EncodeSequence<T>(IEnumerable<T> v, EncodeAction<T> encodeAction)
140
        {
37✔
141
            encoder.EncodeSize(v.Count()); // potentially slow Linq Count()
37✔
142
            foreach (T item in v)
287✔
143
            {
88✔
144
                encodeAction(ref encoder, item);
88✔
145
            }
88✔
146
        }
37✔
147

148
        /// <summary>Encodes a sequence where the element type is an optional Slice type (T?).</summary>
149
        /// <typeparam name="T">The nullable type of the sequence elements.</typeparam>
150
        /// <param name="v">The sequence to encode.</param>
151
        /// <param name="encodeAction">The encode action for a non-null value.</param>
152
        /// <remarks>This method always encodes a bit sequence.</remarks>
153
        public void EncodeSequenceOfOptionals<T>(
154
            IEnumerable<T> v,
155
            EncodeAction<T> encodeAction)
156
        {
14✔
157
            int count = v.Count(); // potentially slow Linq Count()
14✔
158
            encoder.EncodeSize(count);
14✔
159
            if (count > 0)
14✔
160
            {
14✔
161
                BitSequenceWriter bitSequenceWriter = encoder.GetBitSequenceWriter(count);
14✔
162
                foreach (T item in v)
126✔
163
                {
42✔
164
                    bitSequenceWriter.Write(item is not null);
42✔
165
                    if (item is not null)
42✔
166
                    {
28✔
167
                        encodeAction(ref encoder, item);
28✔
168
                    }
28✔
169
                }
42✔
170
            }
14✔
171
        }
14✔
172

173
        /// <summary>Encodes a span of fixed-size numeric values, such as int or ulong.</summary>
174
        /// <typeparam name="T">The span element type.</typeparam>
175
        /// <param name="v">The span of numeric values represented by a <see cref="ReadOnlySpan{T}" />.</param>
176
        public void EncodeSpan<T>(ReadOnlySpan<T> v)
177
            where T : struct
178
        {
3,249✔
179
            // This method works because (as long as) there is no padding in the memory representation of the
180
            // ReadOnlySpan.
181
            encoder.EncodeSize(v.Length);
3,249✔
182
            if (!v.IsEmpty)
3,249✔
183
            {
3,249✔
184
                encoder.WriteByteSpan(MemoryMarshal.AsBytes(v));
3,249✔
185
            }
3,249✔
186
        }
3,249✔
187

188
        /// <summary>Copies a sequence of bytes to the underlying buffer writer.</summary>
189
        /// <param name="v">The sequence to copy.</param>
190
        public void WriteByteSequence(ReadOnlySequence<byte> v)
191
        {
10✔
192
            if (!v.IsEmpty)
10✔
193
            {
5✔
194
                if (v.IsSingleSegment)
5✔
195
                {
5✔
196
                    encoder.WriteByteSpan(v.FirstSpan);
5✔
197
                }
5✔
198
                else
199
                {
×
200
                    foreach (ReadOnlyMemory<byte> buffer in v)
×
201
                    {
×
202
                        encoder.WriteByteSpan(buffer.Span);
×
203
                    }
×
204
                }
×
205
            }
5✔
206
        }
10✔
207
    }
208
}
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