// Copyright Epic Games, Inc. All Rights Reserved.
using System.Diagnostics.CodeAnalysis;
using MongoDB.Bson;
namespace HordeServer.Utilities
{
///
/// Extension methods for BsonDocument
///
public static class BsonDocumentExtensions
{
///
/// Gets a property value from a document or subdocument, indicated with dotted notation
///
/// Document to get a property for
/// Name of the property
/// Expected type of the property
/// Receives the property value
/// True if the property exists and was of the correct type
public static bool TryGetPropertyValue(this BsonDocument document, string name, BsonType type, [NotNullWhen(true)] out BsonValue? outValue)
{
int dotIdx = name.IndexOf('.', StringComparison.Ordinal);
if (dotIdx == -1)
{
return TryGetDirectPropertyValue(document, name, type, out outValue);
}
BsonValue? docValue;
if (TryGetDirectPropertyValue(document, name.Substring(0, dotIdx), BsonType.Document, out docValue))
{
return TryGetPropertyValue(docValue.AsBsonDocument, name.Substring(dotIdx + 1), type, out outValue);
}
outValue = null;
return false;
}
///
/// Gets a property value that's an immediate child of the document
///
/// Document to get a property for
/// Name of the property
/// Expected type of the property
/// Receives the property value
/// True if the property exists and was of the correct type
private static bool TryGetDirectPropertyValue(this BsonDocument document, string name, BsonType type, [NotNullWhen(true)] out BsonValue? outValue)
{
BsonValue value;
if (document.TryGetValue(name, out value) && value.BsonType == type)
{
outValue = value;
return true;
}
else
{
outValue = null;
return false;
}
}
///
/// Gets an int32 value from the document
///
/// Document to get a property for
/// Name of the property
/// Receives the property value
/// True if the property was retrieved
public static bool TryGetInt32(this BsonDocument document, string name, out int outValue)
{
BsonValue? value;
if (document.TryGetPropertyValue(name, BsonType.Int32, out value))
{
outValue = value.AsInt32;
return true;
}
else
{
outValue = 0;
return false;
}
}
///
/// Gets a string value from the document
///
/// Document to get a property for
/// Name of the property
/// Receives the property value
/// True if the property was retrieved
public static bool TryGetString(this BsonDocument document, string name, [NotNullWhen(true)] out string? outValue)
{
BsonValue? value;
if (document.TryGetPropertyValue(name, BsonType.String, out value))
{
outValue = value.AsString;
return true;
}
else
{
outValue = null;
return false;
}
}
}
}