Skip to content

Commit

Permalink
Make FluentBundle abstract
Browse files Browse the repository at this point in the history
  • Loading branch information
Ygg01 committed Jan 3, 2024
1 parent 9493d9d commit ebca66b
Show file tree
Hide file tree
Showing 9 changed files with 420 additions and 259 deletions.
8 changes: 4 additions & 4 deletions Linguini.Bundle.Test/Unit/BundleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public void TestFuncAddBehavior()
bundle.TryAddFunction("id", _idFunc);

Assert.That(bundle.TryAddFunction("id", _zeroFunc), Is.False);
Assert.Throws<KeyNotFoundException>(() => bundle.AddFunctionUnchecked("id", _zeroFunc));
Assert.Throws<ArgumentException>(() => bundle.AddFunctionUnchecked("id", _zeroFunc));
}

[Test]
Expand Down Expand Up @@ -287,7 +287,7 @@ public void TestDynamicReference(string input)
var (bundle, err) = LinguiniBuilder.Builder(useExperimental: true).Locale("en-US")
.AddResource(input)
.Build();
Assert.That(err, Is.Empty);
Assert.That(err, Is.Null);
var args = new Dictionary<string, IFluentType>()
{
["attacker"] = (FluentReference)"cat",
Expand Down Expand Up @@ -317,7 +317,7 @@ public void TestMacrosFail()
var (bundle, err) = LinguiniBuilder.Builder(useExperimental: true).Locale("en-US")
.AddResource(Macros)
.Build();
Assert.That(err, Is.Empty);
Assert.That(err, Is.Null);
var args = new Dictionary<string, IFluentType>
{
["style"] = (FluentString)"chicago",
Expand All @@ -344,7 +344,7 @@ public void TestDynamicSelectors()
.Locale("en-US")
.AddResource(DynamicSelectors)
.Build();
Assert.That(err, Is.Empty);
Assert.That(err, Is.Null);
var args = new Dictionary<string, IFluentType>
{
["object"] = (FluentReference)"creature-elf",
Expand Down
10 changes: 8 additions & 2 deletions Linguini.Bundle.Test/Yaml/YamlSuiteParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ public void YamlTestSuiteMethod(ResolverTestSuite parsedTestSuite, LinguiniBuild
foreach (var res in parsedTestSuite.Resources)
{
bundle.AddResource(res, out var err);
errors.AddRange(err);
if (err != null)
{
errors.AddRange(err);
}
}

if (parsedTestSuite.Bundle != null)
Expand Down Expand Up @@ -147,7 +150,10 @@ public void YamlTestSuiteMethod(ResolverTestSuite parsedTestSuite, LinguiniBuild
else
{
testBundle.AddResource(res, out var errs);
errors.AddRange(errs);
if (errs != null)
{
errors.AddRange(errs);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Linguini.Bundle/Builder/FluentBundleOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class FluentBundleOption
public bool UseIsolating { get; init; } = true;
public byte MaxPlaceable { get; init; } = 100;

public IList<string> Locales { get; init; } = new List<string>();
public List<string> Locales { get; init; } = new List<string>();

public IDictionary<string, ExternalFunction> Functions { get; init; } =
new Dictionary<string, ExternalFunction>();
Expand Down
16 changes: 10 additions & 6 deletions Linguini.Bundle/Builder/LinguiniBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public interface IBuildStep : IStep
{
FluentBundle UncheckedBuild();

(FluentBundle, List<FluentError>) Build();
(FluentBundle, List<FluentError>?) Build();
}

public interface IReadyStep : IBuildStep
Expand All @@ -65,7 +65,6 @@ private class StepBuilder : IReadyStep, ILocaleStep, IResourceStep
private CultureInfo _culture;
private readonly List<string> _locales = new();
private readonly List<Resource> _resources = new();
private readonly List<object> _source = new();
private bool _useIsolating;
private Func<IFluentType, string>? _formatterFunc;
private Func<string, string>? _transformFunc;
Expand Down Expand Up @@ -113,15 +112,15 @@ public FluentBundle UncheckedBuild()
{
var (bundle, errors) = Build();

if (errors.Count > 0)
if (errors is { Count: > 0 })
{
throw new LinguiniException(errors);
}

return bundle;
}

public (FluentBundle, List<FluentError>) Build()
public (FluentBundle, List<FluentError>?) Build()
{
var concurrent = new FluentBundleOption
{
Expand All @@ -134,18 +133,23 @@ public FluentBundle UncheckedBuild()
};
var bundle = FluentBundle.MakeUnchecked(concurrent);
bundle.Culture = _culture;
List<FluentError>? errors = null;

var errors = new List<FluentError>();
if (_functions.Count > 0)
{
bundle.AddFunctions(_functions, out var funcErr);
errors.AddRange(funcErr);
if (funcErr != null)
{
errors ??= new List<FluentError>();
errors.AddRange(funcErr);
}
}

foreach (var resource in _resources)
{
if (!bundle.AddResource(resource,out var resErr))
{
errors ??= new List<FluentError>();
errors.AddRange(resErr);
}
}
Expand Down
125 changes: 125 additions & 0 deletions Linguini.Bundle/ConcurrentBundle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Linguini.Bundle.Errors;
using Linguini.Bundle.Types;
using Linguini.Syntax.Ast;

// ReSharper disable UnusedType.Global

namespace Linguini.Bundle
{
public sealed class ConcurrentBundle : FluentBundle
{
internal ConcurrentDictionary<string, FluentFunction> _funcList = new();
private ConcurrentDictionary<string, AstTerm> _terms = new();
private ConcurrentDictionary<string, AstMessage> _messages = new();

/// <inheritdoc />
protected override void AddMessageOverriding(AstMessage message)
{
_messages[message.GetId()] = message;
}

/// <inheritdoc />
protected override void AddTermOverriding(AstTerm term)
{
_terms[term.GetId()] = term;
}

/// <inheritdoc />
protected override bool TryAddTerm(AstTerm term, List<FluentError>? errors)
{
if (_terms.TryAdd(term.GetId(), term)) return true;
errors ??= new List<FluentError>();
errors.Add(new OverrideFluentError(term.GetId(), EntryKind.Term));
return false;
}

/// <inheritdoc />
protected override bool TryAddMessage(AstMessage message, List<FluentError>? errors)
{
if (_messages.TryAdd(message.GetId(), message)) return true;
errors ??= new List<FluentError>();
errors.Add(new OverrideFluentError(message.GetId(), EntryKind.Message));
return false;
}


/// <inheritdoc />
public override bool TryAddFunction(string funcName, ExternalFunction fluentFunction)
{
return _funcList.TryAdd(funcName, fluentFunction);
}

/// <inheritdoc />
public override void AddFunctionOverriding(string funcName, ExternalFunction fluentFunction)
{
_funcList[funcName] = fluentFunction;
}

/// <inheritdoc />
public override void AddFunctionUnchecked(string funcName, ExternalFunction fluentFunction)
{
if (_funcList.TryAdd(funcName, fluentFunction)) return;
throw new ArgumentException($"Function with name {funcName} already exist");
}

/// <inheritdoc />
public override bool HasMessage(string identifier)
{
return _messages.ContainsKey(identifier);
}

/// <inheritdoc />
public override bool TryGetAstMessage(string ident, [NotNullWhen(true)] out AstMessage? message)
{
return _messages.TryGetValue(ident, out message);
}

/// <inheritdoc />
public override bool TryGetAstTerm(string ident, [NotNullWhen(true)] out AstTerm? term)
{
return _terms.TryGetValue(ident, out term);
}


/// <inheritdoc />
public override bool TryGetFunction(string funcName, [NotNullWhen(true)] out FluentFunction? function)
{
return _funcList.TryGetValue(funcName, out function);
}

/// <inheritdoc />
public override IEnumerable<string> GetMessageEnumerable()
{
return _messages.Keys.ToArray();
}

/// <inheritdoc />
public override IEnumerable<string> GetFuncEnumerable()
{
return _funcList.Keys.ToArray();
}

/// <inheritdoc />
public override IEnumerable<string> GetTermEnumerable()
{
return _terms.Keys.ToArray();
}


/// <inheritdoc />
public override FluentBundle DeepClone()
{
return new ConcurrentBundle()
{
_funcList = new ConcurrentDictionary<string, FluentFunction>(_funcList),
_terms = new ConcurrentDictionary<string, AstTerm>(_terms),
_messages = new ConcurrentDictionary<string, AstMessage>(_messages),
};
}
}
}
Loading

0 comments on commit ebca66b

Please sign in to comment.