Skip to content

Commit be4f7e0

Browse files
committed
refactor RichMultiString to not extend Dictionary, rework proxies to match
1 parent 89158bc commit be4f7e0

5 files changed

Lines changed: 351 additions & 54 deletions

File tree

backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -655,11 +655,7 @@ private ExampleSentence FromLexExampleSentence(Guid senseGuid, ILexExampleSenten
655655
Id = sentence.Guid,
656656
SenseId = senseGuid,
657657
Sentence = FromLcmMultiString(sentence.Example),
658-
Reference =
659-
sentence.Reference.Length == 0
660-
? null
661-
: RichTextMapping.FromTsString(sentence.Reference,
662-
h => h is null ? null : (WritingSystemId?)GetWritingSystemId(h.Value)),
658+
Reference = ToRichString(sentence.Reference),
663659
Translation = translation is null ? new() : FromLcmMultiString(translation),
664660
};
665661
}
@@ -684,16 +680,25 @@ private RichMultiString FromLcmMultiString(IMultiString multiString)
684680
{
685681
var tsString = multiString.GetStringFromIndex(i, out var ws);
686682

687-
result.Add(GetWritingSystemId(ws), RichTextMapping.FromTsString(tsString, h =>
688-
{
689-
if (h is null) return null;
690-
return GetWritingSystemId(h.Value);
691-
}));
683+
var richString = ToRichString(tsString);
684+
if (richString is null) continue;
685+
result.Add(GetWritingSystemId(ws), richString);
692686
}
693687

694688
return result;
695689
}
696690

691+
internal RichString? ToRichString(ITsString? tsString)
692+
{
693+
if (tsString is null or {Length: 0}) return null;
694+
return RichTextMapping.FromTsString(tsString,
695+
h =>
696+
{
697+
if (h is null) return null;
698+
return GetWritingSystemId(h.Value);
699+
});
700+
}
701+
697702
public IAsyncEnumerable<Entry> GetEntries(QueryOptions? options = null)
698703
{
699704
return GetEntries(null, options);

backend/FwLite/FwDataMiniLcmBridge/Api/UpdateProxy/UpdateDictionaryProxy.cs

Lines changed: 201 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections;
2+
using System.Diagnostics.CodeAnalysis;
23
using MiniLcm.Models;
34
using SIL.LCModel.Core.KernelInterfaces;
45
using SIL.LCModel.Core.Text;
@@ -19,12 +20,6 @@ public void Add(WritingSystemId key, string value)
1920
multiString.set_String(writingSystemHandle, TsStringUtils.MakeString(value, writingSystemHandle));
2021
}
2122

22-
public void Add(WritingSystemId key, RichString value)
23-
{
24-
var writingSystemHandle = lexboxLcmApi.GetWritingSystemHandle(key);
25-
multiString.set_String(writingSystemHandle, RichTextMapping.ToTsString(value, ws => lexboxLcmApi.GetWritingSystemHandle(ws)));
26-
}
27-
2823
public bool ContainsKey(WritingSystemId key)
2924
{
3025
if (multiString.StringCount == 0) return false;
@@ -52,13 +47,9 @@ public void Add(object key, object? value)
5247
{
5348
Add(keyWs, valueStr);
5449
}
55-
else if (value is RichString valueRich)
56-
{
57-
Add(keyWs, valueRich);
58-
}
5950
else
6051
{
61-
throw new ArgumentException("unable to convert value to string", nameof(value));
52+
throw new ArgumentException($"unable to convert value {value} to string", nameof(value));
6253
}
6354
}
6455

@@ -185,9 +176,15 @@ public void CopyTo(Array array, int index)
185176
public bool IsReadOnly => false;
186177

187178

188-
public bool TryGetValue(WritingSystemId key, out string value)
179+
public bool TryGetValue(WritingSystemId key, [MaybeNullWhen(false)] out string value)
189180
{
190-
throw new NotSupportedException();
181+
if (!ContainsKey(key))
182+
{
183+
value = null;
184+
return false;
185+
}
186+
value = this[key];
187+
return true;
191188
}
192189

193190
public ICollection<WritingSystemId> Keys => [];
@@ -198,3 +195,194 @@ public bool TryGetValue(WritingSystemId key, out string value)
198195

199196
public ICollection<string> Values => [];
200197
}
198+
199+
public class UpdateRichMultiStringDictionaryProxy(ITsMultiString multiString, FwDataMiniLcmApi lexboxLcmApi)
200+
: IDictionary<WritingSystemId, RichString>, IDictionary
201+
{
202+
public void Add(KeyValuePair<WritingSystemId, RichString> item)
203+
{
204+
Add(item.Key, item.Value);
205+
}
206+
207+
public void Add(WritingSystemId key, RichString value)
208+
{
209+
var writingSystemHandle = lexboxLcmApi.GetWritingSystemHandle(key);
210+
multiString.set_String(writingSystemHandle,
211+
RichTextMapping.ToTsString(value, ws => lexboxLcmApi.GetWritingSystemHandle(ws)));
212+
}
213+
214+
public bool ContainsKey(WritingSystemId key)
215+
{
216+
if (multiString.StringCount == 0) return false;
217+
var tsString = multiString.get_String(lexboxLcmApi.GetWritingSystemHandle(key));
218+
return tsString.Length > 0;
219+
}
220+
221+
public void Add(object key, object? value)
222+
{
223+
WritingSystemId keyWs;
224+
if (key is WritingSystemId typed)
225+
{
226+
keyWs = typed;
227+
}
228+
else if (key is string keyStr)
229+
{
230+
keyWs = keyStr;
231+
}
232+
else
233+
{
234+
throw new ArgumentException("unable to convert key to writing system id", nameof(key));
235+
}
236+
237+
if (value is RichString valueRich)
238+
{
239+
Add(keyWs, valueRich);
240+
}
241+
else
242+
{
243+
throw new ArgumentException("unable to convert value to string", nameof(value));
244+
}
245+
}
246+
247+
public bool Contains(object key)
248+
{
249+
return ContainsKey(key as WritingSystemId? ?? key as string ??
250+
throw new ArgumentException("unable to convert key to writing system id", nameof(key)));
251+
}
252+
253+
254+
public RichString this[WritingSystemId key]
255+
{
256+
get
257+
{
258+
var tsString = multiString.get_String(lexboxLcmApi.GetWritingSystemHandle(key));
259+
return lexboxLcmApi.ToRichString(tsString) ?? throw new ArgumentException($"unable to find rich string for writing system {key}");
260+
}
261+
set
262+
{
263+
var writingSystemHandle = lexboxLcmApi.GetWritingSystemHandle(key);
264+
multiString.set_String(writingSystemHandle, RichTextMapping.ToTsString(value, id => lexboxLcmApi.GetWritingSystemHandle(id)));
265+
}
266+
}
267+
268+
public object? this[object key]
269+
{
270+
get =>
271+
key switch
272+
{
273+
WritingSystemId keyWs => this[keyWs],
274+
string keyStr => this[keyStr],
275+
_ => throw new ArgumentException("unable to convert key to writing system id", nameof(key))
276+
};
277+
set
278+
{
279+
var valStr = value as RichString ??
280+
throw new ArgumentException("unable to convert value to string", nameof(value));
281+
if (key is WritingSystemId keyWs)
282+
{
283+
this[keyWs] = valStr;
284+
}
285+
else if (key is string keyStr)
286+
{
287+
this[keyStr] = valStr;
288+
}
289+
else
290+
{
291+
throw new ArgumentException("unable to convert key to writing system id", nameof(key));
292+
}
293+
}
294+
}
295+
296+
IDictionaryEnumerator IDictionary.GetEnumerator()
297+
{
298+
throw new NotSupportedException();
299+
}
300+
301+
public void Remove(object key)
302+
{
303+
if (key is WritingSystemId keyWs)
304+
{
305+
Remove(keyWs);
306+
}
307+
else if (key is string keyStr)
308+
{
309+
Remove(keyStr);
310+
}
311+
else
312+
{
313+
throw new ArgumentException($"unable to convert key {key} to writing system id", nameof(key));
314+
}
315+
}
316+
317+
public bool Remove(WritingSystemId key)
318+
{
319+
var containedKey = ContainsKey(key);
320+
var writingSystemHandle = lexboxLcmApi.GetWritingSystemHandle(key);
321+
multiString.set_String(writingSystemHandle, null);
322+
return containedKey;
323+
}
324+
325+
public bool IsFixedSize => false;
326+
327+
public IEnumerator<KeyValuePair<WritingSystemId, RichString>> GetEnumerator()
328+
{
329+
throw new NotSupportedException();
330+
}
331+
332+
IEnumerator IEnumerable.GetEnumerator()
333+
{
334+
return GetEnumerator();
335+
}
336+
337+
public void Clear()
338+
{
339+
throw new NotSupportedException();
340+
}
341+
342+
public bool Contains(KeyValuePair<WritingSystemId, RichString> item)
343+
{
344+
throw new NotSupportedException();
345+
}
346+
347+
public void CopyTo(KeyValuePair<WritingSystemId, RichString>[] array, int arrayIndex)
348+
{
349+
throw new NotSupportedException();
350+
}
351+
352+
public bool Remove(KeyValuePair<WritingSystemId, RichString> item)
353+
{
354+
throw new NotSupportedException();
355+
}
356+
357+
public void CopyTo(Array array, int index)
358+
{
359+
}
360+
361+
public int Count => throw new NotSupportedException();
362+
363+
public bool IsSynchronized => false;
364+
365+
public object SyncRoot => this;
366+
367+
public bool IsReadOnly => false;
368+
369+
370+
public bool TryGetValue(WritingSystemId key, [MaybeNullWhen(false)] out RichString value)
371+
{
372+
if (!ContainsKey(key))
373+
{
374+
value = null;
375+
return false;
376+
}
377+
value = this[key];
378+
return true;
379+
}
380+
381+
public ICollection<WritingSystemId> Keys => [];
382+
383+
ICollection IDictionary.Values => Array.Empty<object>();
384+
385+
ICollection IDictionary.Keys => Array.Empty<object>();
386+
387+
public ICollection<RichString> Values => [];
388+
}

backend/FwLite/FwDataMiniLcmBridge/Api/UpdateProxy/UpdateEntryProxy.cs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,7 @@ public override MultiString Copy()
8282
}
8383

8484

85-
public class UpdateRichMultiStringProxy(ITsMultiString multiString, FwDataMiniLcmApi lexboxLcmApi) : RichMultiString, IDictionary
85+
public class UpdateRichMultiStringProxy(ITsMultiString multiString, FwDataMiniLcmApi lexboxLcmApi) : RichMultiString(new
86+
UpdateRichMultiStringDictionaryProxy(multiString, lexboxLcmApi))
8687
{
87-
private UpdateDictionaryProxy proxy = new(multiString, lexboxLcmApi);
88-
89-
void IDictionary.Add(object key, object? value)
90-
{
91-
((IDictionary)proxy).Add(key, value);
92-
}
93-
94-
void IDictionary.Remove(object key)
95-
{
96-
((IDictionary)proxy).Remove(key);
97-
}
98-
99-
object? IDictionary.this[object key]
100-
{
101-
get => ((IDictionary)proxy)[key];
102-
set => ((IDictionary)proxy)[key] = value;
103-
}
10488
}

backend/FwLite/MiniLcm.Tests/RichMultiStringTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public void JsonPatchCanUpdateRichMultiString()
208208
patch.Replace(ms => ms["en"], new RichString("updated"));
209209
patch.ApplyTo(ms);
210210
ms.Should().ContainKey("en");
211-
ms["en"].Should().BeEquivalentTo(new RichString("updated"));
211+
ms["en"].Should().BeEquivalentTo(new RichString("updated", "en"));
212212
}
213213

214214
//this test emulates any existing data that was stored as a string
@@ -220,7 +220,7 @@ public void JsonPatchCanUpdateRichMultiStringWhenValueIsString()
220220
patch.Operations.Add(new Operation<RichMultiString>("replace", "/en", null, "updated"));
221221
patch.ApplyTo(ms);
222222
ms.Should().ContainKey("en");
223-
ms["en"].Should().BeEquivalentTo(new RichString("updated"));
223+
ms["en"].Should().BeEquivalentTo(new RichString("updated", "en"));
224224
}
225225

226226
[Fact]

0 commit comments

Comments
 (0)