Skip to content

Commit

Permalink
Improve docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ygg01 committed Jan 23, 2024
1 parent 141e9f6 commit 251f15e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 74 deletions.
61 changes: 26 additions & 35 deletions Linguini.Bundle/ConcurrentBundle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,33 @@

namespace Linguini.Bundle
{
/// <summary>
/// Represents a thread-safe implementation of the FluentBundle class.
///
/// `ConcurrentBundle` implements the <see cref="IReadBundle"/> interface.
/// </summary>
public sealed class ConcurrentBundle : FluentBundle, IEquatable<ConcurrentBundle>
{
internal ConcurrentDictionary<string, FluentFunction> Functions = new();
private ConcurrentDictionary<string, AstTerm> _terms = new();
private ConcurrentDictionary<string, AstMessage> _messages = new();

public static ConcurrentBundle Thaw(FrozenBundle frozenBundle)
{
return new ConcurrentBundle
{
_messages = new ConcurrentDictionary<string, AstMessage>(frozenBundle.Messages),
Functions = new ConcurrentDictionary<string, FluentFunction>(frozenBundle.Functions),
_terms = new ConcurrentDictionary<string, AstTerm>(frozenBundle.Terms),
FormatterFunc = frozenBundle.FormatterFunc,
Locales = frozenBundle.Locales,
UseIsolating = frozenBundle.UseIsolating,
MaxPlaceable = frozenBundle.MaxPlaceable,
EnableExtensions = frozenBundle.EnableExtensions,
TransformFunc = frozenBundle.TransformFunc,
Culture = frozenBundle.Culture
};
}
internal ConcurrentDictionary<string, AstTerm> Terms = new();
internal ConcurrentDictionary<string, AstMessage> Messages = new();

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

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

/// <inheritdoc />
protected override bool TryAddTerm(AstTerm term, List<FluentError>? errors)
{
if (_terms.TryAdd(term.GetId(), term)) return true;
if (Terms.TryAdd(term.GetId(), term)) return true;
errors ??= new List<FluentError>();
errors.Add(new OverrideFluentError(term.GetId(), EntryKind.Term));
return false;
Expand All @@ -60,7 +48,7 @@ protected override bool TryAddTerm(AstTerm term, List<FluentError>? errors)
/// <inheritdoc />
protected override bool TryAddMessage(AstMessage message, List<FluentError>? errors)
{
if (_messages.TryAdd(message.GetId(), message)) return true;
if (Messages.TryAdd(message.GetId(), message)) return true;
errors ??= new List<FluentError>();
errors.Add(new OverrideFluentError(message.GetId(), EntryKind.Message));
return false;
Expand Down Expand Up @@ -89,19 +77,19 @@ public override void AddFunctionUnchecked(string funcName, ExternalFunction flue
/// <inheritdoc />
public override bool HasMessage(string identifier)
{
return _messages.ContainsKey(identifier);
return Messages.ContainsKey(identifier);
}

/// <inheritdoc />
public override bool TryGetAstMessage(string ident, [NotNullWhen(true)] out AstMessage? message)
{
return _messages.TryGetValue(ident, out 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);
return Terms.TryGetValue(ident, out term);
}


Expand All @@ -114,7 +102,7 @@ public override bool TryGetFunction(string funcName, [NotNullWhen(true)] out Flu
/// <inheritdoc />
public override IEnumerable<string> GetMessageEnumerable()
{
return _messages.Keys;
return Messages.Keys;
}

/// <inheritdoc />
Expand All @@ -126,19 +114,22 @@ public override IEnumerable<string> GetFuncEnumerable()
/// <inheritdoc />
public override IEnumerable<string> GetTermEnumerable()
{
return _terms.Keys;
return Terms.Keys;
}

/// <inheritdoc/>
internal override IDictionary<string, AstMessage> GetMessagesDictionary()
{
return _messages;
return Messages;
}

/// <inheritdoc/>
internal override IDictionary<string, AstTerm> GetTermsDictionary()
{
return _terms;
return Terms;
}

/// <inheritdoc/>
internal override IDictionary<string, FluentFunction> GetFunctionDictionary()
{
return Functions;
Expand All @@ -150,8 +141,8 @@ public override FluentBundle DeepClone()
return new ConcurrentBundle
{
Functions = new ConcurrentDictionary<string, FluentFunction>(Functions),
_terms = new ConcurrentDictionary<string, AstTerm>(_terms),
_messages = new ConcurrentDictionary<string, AstMessage>(_messages),
Terms = new ConcurrentDictionary<string, AstTerm>(Terms),
Messages = new ConcurrentDictionary<string, AstMessage>(Messages),
Culture = (CultureInfo)Culture.Clone(),
Locales = new List<string>(Locales),
UseIsolating = UseIsolating,
Expand All @@ -167,8 +158,8 @@ public bool Equals(ConcurrentBundle? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && Functions.SequenceEqual(other.Functions) && _terms.SequenceEqual(other._terms) &&
_messages.SequenceEqual(other._messages);
return base.Equals(other) && Functions.SequenceEqual(other.Functions) && Terms.SequenceEqual(other.Terms) &&
Messages.SequenceEqual(other.Messages);
}

/// <inheritdoc/>
Expand All @@ -180,7 +171,7 @@ public override bool Equals(object? obj)
/// <inheritdoc/>
public override int GetHashCode()
{
return HashCode.Combine(base.GetHashCode(), Functions, _terms, _messages);
return HashCode.Combine(base.GetHashCode(), Functions, Terms, Messages);
}
}
}
9 changes: 9 additions & 0 deletions Linguini.Bundle/FrozenBundle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,13 @@ internal FrozenBundle(FluentBundle bundle)
Functions = new Dictionary<string, FluentFunction>(bundle.GetFunctionDictionary());
}
#endif
/// <inheritdoc/>
public bool HasMessage(string identifier)
{
return Messages.ContainsKey(identifier);
}

/// <inheritdoc/>
public string FormatPattern(Pattern pattern, IDictionary<string, IFluentType>? args,
[NotNullWhen(false)] out IList<FluentError>? errors)
{
Expand All @@ -129,36 +131,43 @@ public string FormatPattern(Pattern pattern, IDictionary<string, IFluentType>? a
return value.AsString();
}

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

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

/// <inheritdoc/>
public bool TryGetFunction(Identifier id, [NotNullWhen(true)] out FluentFunction? function)
{
return Functions.TryGetValue(id.ToString(), out function);
}

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

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

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

/// <inheritdoc/>
public IEnumerable<string> GetTermEnumerable()
{
return Terms.Keys;
Expand Down
37 changes: 33 additions & 4 deletions Linguini.Bundle/IReadBundle.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Linguini.Bundle.Errors;
Expand All @@ -8,6 +9,9 @@

namespace Linguini.Bundle
{
/// <summary>
/// Represents an interface for reading language bundles.
/// </summary>
public interface IReadBundle
{
/// <summary>
Expand Down Expand Up @@ -197,8 +201,33 @@ public bool TryGetMessage(string id, string? attribute, IDictionary<string, IFlu
}
}

/// <summary>
/// Provides extension methods for working with bundles.
/// </summary>
public static class ReadBundleExtensions
{
/// <summary>
/// Thaws a frozen bundle and returns a new instance of a concurrent bundle.
/// </summary>
/// <param name="frozenBundle">The frozen bundle to thaw.</param>
/// <returns>A new instance of a concurrent bundle.</returns>
public static ConcurrentBundle Thaw(this FrozenBundle frozenBundle)
{
return new ConcurrentBundle
{
Messages = new ConcurrentDictionary<string, AstMessage>(frozenBundle.Messages),
Functions = new ConcurrentDictionary<string, FluentFunction>(frozenBundle.Functions),
Terms = new ConcurrentDictionary<string, AstTerm>(frozenBundle.Terms),
FormatterFunc = frozenBundle.FormatterFunc,
Locales = frozenBundle.Locales,
UseIsolating = frozenBundle.UseIsolating,
MaxPlaceable = frozenBundle.MaxPlaceable,
EnableExtensions = frozenBundle.EnableExtensions,
TransformFunc = frozenBundle.TransformFunc,
Culture = frozenBundle.Culture
};
}

/// <summary>
/// Convenience method for <see cref="IReadBundle.HasAttrMessage"/>
/// </summary>
Expand Down Expand Up @@ -251,8 +280,8 @@ public static bool HasAttrMessage(this IReadBundle bundle, string idWithAttr)
/// <param name="bundle">The bundle to retrieve the message from.</param>
/// <param name="msgWithAttr">The message with attribute</param>
/// <param name="args">Optional arguments to be passed to the attribute message.</param>
/// <param name="errors">When this method returns, contains any errors that occured during retrieval, if any.</param>
/// <param name="message">When this method returns, contains the retrieved attribute message, if it exists.</param>
/// <param name="errors">When this method returns false, contains a list of errors that occurred while trying to retrieve the message; otherwise, null.</param>
/// <param name="message">When this method returns true, contains the retrieved message; otherwise, null.</param>
/// <returns><c>true</c> if the attribute message was successfully retrieved; otherwise, <c>false</c>.</returns>
public static bool TryGetAttrMessage(this IReadBundle bundle, string msgWithAttr,
IDictionary<string, IFluentType>? args,
Expand All @@ -266,8 +295,8 @@ public static bool TryGetAttrMessage(this IReadBundle bundle, string msgWithAttr
/// </summary>
/// <param name="bundle">The bundle to retrieve the message from.</param>
/// <param name="id">The identifier of the message.</param>
/// <param name="attribute">The attribute of the message (optional).</param>
/// <param name="args">The arguments for the message (optional).</param>
/// <param name="attribute">Optional attribute of the message.</param>
/// <param name="args">Optional arguments to be passed to the attribute message.</param>
/// <param name="errors">When this method returns false, contains a list of errors that occurred while trying to retrieve the message; otherwise, null.</param>
/// <param name="message">When this method returns true, contains the retrieved message; otherwise, null.</param>
/// <returns>True if the message was successfully retrieved, otherwise false.</returns>
Expand Down
Loading

0 comments on commit 251f15e

Please sign in to comment.