@@ -640,7 +640,7 @@ private double AsBaseNumericType(AmountOfSubstanceUnit unit)
640
640
/// </exception>
641
641
public static AmountOfSubstance Parse ( string str )
642
642
{
643
- return Parse ( str , null ) ;
643
+ return ParseInternal ( str , null ) ;
644
644
}
645
645
646
646
/// <summary>
@@ -653,7 +653,7 @@ public static AmountOfSubstance Parse(string str)
653
653
/// </example>
654
654
public static bool TryParse ( [ CanBeNull ] string str , out AmountOfSubstance result )
655
655
{
656
- return TryParse ( str , null , out result ) ;
656
+ return TryParseInternal ( str , null , out result ) ;
657
657
}
658
658
659
659
/// <summary>
@@ -667,7 +667,140 @@ public static bool TryParse([CanBeNull] string str, out AmountOfSubstance result
667
667
/// <exception cref="UnitsNetException">Error parsing string.</exception>
668
668
public static AmountOfSubstanceUnit ParseUnit ( string str )
669
669
{
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 ;
671
804
}
672
805
673
806
#endregion
0 commit comments