@@ -640,7 +640,7 @@ private double AsBaseNumericType(AmountOfSubstanceUnit unit)
640640 /// </exception>
641641 public static AmountOfSubstance Parse ( string str )
642642 {
643- return Parse ( str , null ) ;
643+ return ParseInternal ( str , null ) ;
644644 }
645645
646646 /// <summary>
@@ -653,7 +653,7 @@ public static AmountOfSubstance Parse(string str)
653653 /// </example>
654654 public static bool TryParse ( [ CanBeNull ] string str , out AmountOfSubstance result )
655655 {
656- return TryParse ( str , null , out result ) ;
656+ return TryParseInternal ( str , null , out result ) ;
657657 }
658658
659659 /// <summary>
@@ -667,7 +667,140 @@ public static bool TryParse([CanBeNull] string str, out AmountOfSubstance result
667667 /// <exception cref="UnitsNetException">Error parsing string.</exception>
668668 public static AmountOfSubstanceUnit ParseUnit ( string str )
669669 {
670- return ParseUnit ( str , ( IFormatProvider ) null ) ;
670+ return ParseUnitInternal ( str , null ) ;
671+ }
672+
673+ public static bool TryParseUnit ( string str , out AmountOfSubstanceUnit unit )
674+ {
675+ return TryParseUnitInternal ( str , null , out unit ) ;
676+ }
677+
678+ /// <summary>
679+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
680+ /// </summary>
681+ /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
682+ /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="UnitSystem.DefaultCulture" />.</param>
683+ /// <example>
684+ /// Length.Parse("5.5 m", new CultureInfo("en-US"));
685+ /// </example>
686+ /// <exception cref="ArgumentNullException">The value of 'str' cannot be null. </exception>
687+ /// <exception cref="ArgumentException">
688+ /// Expected string to have one or two pairs of quantity and unit in the format
689+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
690+ /// </exception>
691+ /// <exception cref="AmbiguousUnitParseException">
692+ /// More than one unit is represented by the specified unit abbreviation.
693+ /// Example: Volume.Parse("1 cup") will throw, because it can refer to any of
694+ /// <see cref="VolumeUnit.MetricCup" />, <see cref="VolumeUnit.UsLegalCup" /> and <see cref="VolumeUnit.UsCustomaryCup" />.
695+ /// </exception>
696+ /// <exception cref="UnitsNetException">
697+ /// If anything else goes wrong, typically due to a bug or unhandled case.
698+ /// We wrap exceptions in <see cref="UnitsNetException" /> to allow you to distinguish
699+ /// Units.NET exceptions from other exceptions.
700+ /// </exception>
701+ internal static AmountOfSubstance ParseInternal ( string str , [ CanBeNull ] IFormatProvider provider )
702+ {
703+ if ( str == null ) throw new ArgumentNullException ( nameof ( str ) ) ;
704+
705+ provider = provider ?? UnitSystem . DefaultCulture ;
706+
707+ return QuantityParser . Parse < AmountOfSubstance , AmountOfSubstanceUnit > ( str , provider ,
708+ delegate ( string value , string unit , IFormatProvider formatProvider2 )
709+ {
710+ var parsedValue = double . Parse ( value , formatProvider2 ) ;
711+ var parsedUnit = ParseUnitInternal ( unit , formatProvider2 ) ;
712+ return From ( parsedValue , parsedUnit ) ;
713+ } , ( x , y ) => From ( x . Moles + y . Moles , BaseUnit ) ) ;
714+ }
715+
716+ /// <summary>
717+ /// Try to parse a string with one or two quantities of the format "<quantity> <unit>".
718+ /// </summary>
719+ /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
720+ /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="UnitSystem.DefaultCulture" />.</param>
721+ /// <param name="result">Resulting unit quantity if successful.</param>
722+ /// <returns>True if successful, otherwise false.</returns>
723+ /// <example>
724+ /// Length.Parse("5.5 m", new CultureInfo("en-US"));
725+ /// </example>
726+ internal static bool TryParseInternal ( [ CanBeNull ] string str , [ CanBeNull ] IFormatProvider provider , out AmountOfSubstance result )
727+ {
728+ result = default ( AmountOfSubstance ) ;
729+
730+ if ( string . IsNullOrWhiteSpace ( str ) )
731+ return false ;
732+
733+ provider = provider ?? UnitSystem . DefaultCulture ;
734+
735+ return QuantityParser . TryParse < AmountOfSubstance , AmountOfSubstanceUnit > ( str , provider ,
736+ delegate ( string value , string unit , IFormatProvider formatProvider2 , out AmountOfSubstance parsedAmountOfSubstance )
737+ {
738+ parsedAmountOfSubstance = default ( AmountOfSubstance ) ;
739+
740+ if ( ! double . TryParse ( value , NumberStyles . Any , formatProvider2 , out var parsedValue ) )
741+ return false ;
742+
743+ if ( ! TryParseUnitInternal ( unit , formatProvider2 , out var parsedUnit ) )
744+ return false ;
745+
746+ parsedAmountOfSubstance = From ( parsedValue , parsedUnit ) ;
747+ return true ;
748+ } , ( x , y ) => From ( x . Moles + y . Moles , BaseUnit ) , out result ) ;
749+ }
750+
751+ /// <summary>
752+ /// Parse a unit string.
753+ /// </summary>
754+ /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
755+ /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="UnitSystem.DefaultCulture" />.</param>
756+ /// <example>
757+ /// Length.ParseUnit("m", new CultureInfo("en-US"));
758+ /// </example>
759+ /// <exception cref="ArgumentNullException">The value of 'str' cannot be null. </exception>
760+ /// <exception cref="UnitsNetException">Error parsing string.</exception>
761+ internal static AmountOfSubstanceUnit ParseUnitInternal ( string str , IFormatProvider provider = null )
762+ {
763+ if ( str == null ) throw new ArgumentNullException ( nameof ( str ) ) ;
764+
765+ var unitSystem = UnitSystem . GetCached ( provider ) ;
766+ var unit = unitSystem . Parse < AmountOfSubstanceUnit > ( str . Trim ( ) ) ;
767+
768+ if ( unit == AmountOfSubstanceUnit . Undefined )
769+ {
770+ var newEx = new UnitsNetException ( "Error parsing string. The unit is not a recognized AmountOfSubstanceUnit." ) ;
771+ newEx . Data [ "input" ] = str ;
772+ newEx . Data [ "provider" ] = provider ? . ToString ( ) ?? "(null)" ;
773+ throw newEx ;
774+ }
775+
776+ return unit ;
777+ }
778+
779+ /// <summary>
780+ /// Parse a unit string.
781+ /// </summary>
782+ /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
783+ /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="UnitSystem.DefaultCulture" />.</param>
784+ /// <param name="unit">The parsed unit if successful.</param>
785+ /// <returns>True if successful, otherwise false.</returns>
786+ /// <example>
787+ /// Length.ParseUnit("m", new CultureInfo("en-US"));
788+ /// </example>
789+ internal static bool TryParseUnitInternal ( string str , IFormatProvider provider , out AmountOfSubstanceUnit unit )
790+ {
791+ unit = AmountOfSubstanceUnit . Undefined ;
792+
793+ if ( string . IsNullOrWhiteSpace ( str ) )
794+ return false ;
795+
796+ var unitSystem = UnitSystem . GetCached ( provider ) ;
797+ if ( ! unitSystem . TryParse < AmountOfSubstanceUnit > ( str . Trim ( ) , out unit ) )
798+ return false ;
799+
800+ if ( unit == AmountOfSubstanceUnit . Undefined )
801+ return false ;
802+
803+ return true ;
671804 }
672805
673806 #endregion
0 commit comments