// 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; } } } }