<commit_before>﻿using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace NMoneys.Serialization.Json_NET
{
	#region converters

	/// <summary>
	/// Converts a <see cref="Money"/> instance to and from JSON in the canonical way.
	/// </summary>
	/// <remarks>The canonical way is the one implemented in NMoneys itself, with an <c>Amount</c>
	/// numeric property and a <c>Currency</c> object with a three-letter code <c>IsoCode"</c> property.
	/// <para>
	/// Property casing must be configured apart from this converter using, for instance, another
	/// <see cref="IContractResolver"/>
	/// </para>
	/// </remarks>
	/// <example>
	/// <code>{"Amount" : 123.4, "Currency" : {"IsoCode" : "XXX"}}</code>
	/// <code>{"amount" : 123.4, "currency" : {"isoCode" : "XXX"}}</code>
	/// </example>
	public class CanonicalMoneyConverter : JsonConverter
	{
		private readonly IMoneyWriter _writer;
		private readonly IMoneyReader _reader;

		public CanonicalMoneyConverter()
		{
			_writer = new CanonicalMoneyWriter();
			_reader = new CanonicalMoneyReader();
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var instance = (Money) value;

			_writer.WriteTo(instance, serializer.ContractResolver, writer);
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			Money? money = default(Money?);
			var token = JToken.ReadFrom(reader);
			if (token.HasValues)
			{
				money = new Money(
					_reader.ReadAmount(token, serializer.ContractResolver),
					_reader.ReadCurrencyCode(token, serializer.ContractResolver));
			}
			return MoneyReader.AdaptNullables(objectType, money);
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(Money) || objectType == typeof(Money?);
		}
	}

	/// <summary>
	/// Converts a <see cref="Money"/> instance to and from JSON in a default (standard) way.
	/// </summary>
	/// <remarks>The default (standard) way is the one that a normal serializer would do for a money instance,
	/// with an <c>Amount</c> numeric property and a <c>Currency</c> code. The <c>Currency</c> property can be
	/// serialized either as a string (the default or providing <see cref="CurrencyStyle.Alphabetic"/>) or as
	/// a number (providing <see cref="CurrencyStyle.Numeric"/>).
	/// <para>
	/// Property casing must be configured apart from this converter using, for instance, another
	/// <see cref="IContractResolver"/>
	/// </para>
	/// </remarks>
	/// <example>
	/// <code>{"Amount" : 123.4, "Currency" : "XXX"}</code>
	/// <code>{"amount" : 123.4, "currency" : 999}</code><commit_msg>add nullable handling documentation<commit_after>﻿using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace NMoneys.Serialization.Json_NET
{
	#region converters

	/// <summary>
	/// Converts a <see cref="Money"/> instance to and from JSON in the canonical way.
	/// </summary>
	/// <remarks>The canonical way is the one implemented in NMoneys itself, with an <c>Amount</c>
	/// numeric property and a <c>Currency</c> object with a three-letter code <c>IsoCode"</c> property.
	/// <para>
	/// Property casing must be configured apart from this converter using, for instance, another
	/// <see cref="IContractResolver"/>
	/// </para>
	/// <para>This converter can handle conversion to and from <see cref="Nullable{Money}"/> as well.</para>
	/// </remarks>
	/// <example>
	/// <code>{"Amount" : 123.4, "Currency" : {"IsoCode" : "XXX"}}</code>
	/// <code>{"amount" : 123.4, "currency" : {"isoCode" : "XXX"}}</code>
	/// </example>
	public class CanonicalMoneyConverter : JsonConverter
	{
		private readonly IMoneyWriter _writer;
		private readonly IMoneyReader _reader;

		public CanonicalMoneyConverter()
		{
			_writer = new CanonicalMoneyWriter();
			_reader = new CanonicalMoneyReader();
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var instance = (Money) value;

			_writer.WriteTo(instance, serializer.ContractResolver, writer);
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			Money? money = default(Money?);
			var token = JToken.ReadFrom(reader);
			if (token.HasValues)
			{
				money = new Money(
					_reader.ReadAmount(token, serializer.ContractResolver),
					_reader.ReadCurrencyCode(token, serializer.ContractResolver));
			}
			return MoneyReader.AdaptNullables(objectType, money);
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(Money) || objectType == typeof(Money?);
		}
	}

	/// <summary>
	/// Converts a <see cref="Money"/> instance to and from JSON in a default (standard) way.
	/// </summary>
	/// <remarks>The default (standard) way is the one that a normal serializer would do for a money instance,
	/// with an <c>Amount</c> numeric property and a <c>Currency</c> code. The <c>Currency</c> property can be
	/// serialized either as a string (the default or providing <see cref="CurrencyStyle.Alphabetic"/>) or as
	/// a number (providing <see cref="CurrencyStyle.Numeric"/>).
	/// <para>
	/// Property casing must be configured apart from this converter using, for instance, another
	/// <see cref="IContractResolver"/>
	/// </para>
	/// <para>This converter can handle conversion to and from <see cref="Nullable{Money}"/> as well.</para>
	/// </remarks>
	/// <example>
	/// <code>{"Amount" : 123.4, "Currency" : "XXX"}</code>
	/// <code>{"amount" : 123.4, "currency" : 999}</code>
{'fraction_non_alphanumeric': 0.14687280393534785, 'fraction_numerical': 0.0066760365425158116, 'mean_word_length': 3.83276740237691, 'pattern_counts': {'":': 0, '<': 91, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '520623', 'n_tokens_mistral': 1876, 'n_tokens_neox': 1715, 'n_words': 528}