11//
22// Utilities.swift
3- //
3+ //
44//
55// Created by Yaroslav Yashin on 11.07.2022.
66//
@@ -87,7 +87,7 @@ public struct Utilities {
8787 /// Parse a user-supplied string using the number of decimals for particular Ethereum unit.
8888 /// If input is non-numeric or precision is not sufficient - returns nil.
8989 /// Allowed decimal separators are ".", ",".
90- public static func parseToBigUInt( _ amount: String , units: Utilities . Units = . eth ) -> BigUInt ? {
90+ public static func parseToBigUInt( _ amount: String , units: Utilities . Units = . ether ) -> BigUInt ? {
9191 let unitDecimals = units. decimals
9292 return parseToBigUInt ( amount, decimals: unitDecimals)
9393 }
@@ -112,29 +112,14 @@ public struct Utilities {
112112 return mainPart
113113 }
114114
115- /// Formats a BigInt object to String. The supplied number is first divided into integer and decimal part based on "toUnits",
116- /// then limit the decimal part to "decimals" symbols and uses a "decimalSeparator" as a separator.
117- ///
118- /// Returns nil of formatting is not possible to satisfy.
119- static func formatToEthereumUnits( _ bigNumber: BigInt , toUnits: Utilities . Units = . eth, decimals: Int = 4 , decimalSeparator: String = " . " ) -> String ? {
120- let magnitude = BigInt ( bigNumber. magnitude)
121- guard let formatted = formatToEthereumUnits ( magnitude, toUnits: toUnits, decimals: decimals, decimalSeparator: decimalSeparator) else { return nil }
122- switch bigNumber. sign {
123- case . plus:
124- return formatted
125- case . minus:
126- return " - " + formatted
127- }
128- }
129-
130- /// Formats a BigInt object to String. The supplied number is first divided into integer and decimal part based on "toUnits",
115+ /// Formats a BigInt object to String. The supplied number is first divided into integer and decimal part based on "units",
131116 /// then limit the decimal part to "decimals" symbols and uses a "decimalSeparator" as a separator.
132117 /// Fallbacks to scientific format if higher precision is required.
133118 ///
134119 /// Returns nil of formatting is not possible to satisfy.
135- public static func formatToPrecision( _ bigNumber: BigInt , numberDecimals : Int = 18 , formattingDecimals: Int = 4 , decimalSeparator: String = " . " , fallbackToScientific: Bool = false ) -> String ? {
120+ public static func formatToPrecision( _ bigNumber: BigInt , units : Utilities . Units = . ether , formattingDecimals: Int = 4 , decimalSeparator: String = " . " , fallbackToScientific: Bool = false ) -> String {
136121 let magnitude = bigNumber. magnitude
137- guard let formatted = formatToPrecision ( magnitude, numberDecimals : numberDecimals , formattingDecimals: formattingDecimals, decimalSeparator: decimalSeparator, fallbackToScientific: fallbackToScientific) else { return nil }
122+ let formatted = formatToPrecision ( magnitude, units : units , formattingDecimals: formattingDecimals, decimalSeparator: decimalSeparator, fallbackToScientific: fallbackToScientific)
138123 switch bigNumber. sign {
139124 case . plus:
140125 return formatted
@@ -143,31 +128,24 @@ public struct Utilities {
143128 }
144129 }
145130
146- // /// Formats a BigUInt object to String. The supplied number is first divided into integer and decimal part based on "toUnits",
147- // /// then limit the decimal part to "decimals" symbols and uses a "decimalSeparator" as a separator.
148- // ///
149- // /// Returns nil of formatting is not possible to satisfy.
150- // static func formatToEthereumUnits(_ bigNumber: BigUInt, toUnits: Utilities.Units = .eth, decimals: Int = 4, decimalSeparator: String = ".", fallbackToScientific: Bool = false) -> String? {
151- // return formatToPrecision(bigNumber, numberDecimals: toUnits.decimals, formattingDecimals: decimals, decimalSeparator: decimalSeparator, fallbackToScientific: fallbackToScientific)
152- // }
153-
154- /// Formats a BigUInt object to String. The supplied number is first divided into integer and decimal part based on "numberDecimals",
131+ /// Formats a BigUInt object to String. The supplied number is first divided into integer and decimal part based on "units",
155132 /// then limits the decimal part to "formattingDecimals" symbols and uses a "decimalSeparator" as a separator.
156133 /// Fallbacks to scientific format if higher precision is required.
157134 ///
158135 /// Returns nil of formatting is not possible to satisfy.
159- public static func formatToPrecision( _ bigNumber: BigUInt , numberDecimals : Int = 18 , formattingDecimals: Int = 4 , decimalSeparator: String = " . " , fallbackToScientific: Bool = false ) -> String ? {
136+ public static func formatToPrecision( _ bigNumber: BigUInt , units : Utilities . Units = . ether , formattingDecimals: Int = 4 , decimalSeparator: String = " . " , fallbackToScientific: Bool = false ) -> String {
160137 if bigNumber == 0 {
161138 return " 0 "
162139 }
140+ let unitDecimals = units. decimals
163141 var toDecimals = formattingDecimals
164- if numberDecimals < toDecimals {
165- toDecimals = numberDecimals
142+ if unitDecimals < toDecimals {
143+ toDecimals = unitDecimals
166144 }
167- let divisor = BigUInt ( 10 ) . power ( numberDecimals )
145+ let divisor = BigUInt ( 10 ) . power ( unitDecimals )
168146 let ( quotient, remainder) = bigNumber. quotientAndRemainder ( dividingBy: divisor)
169147 var fullRemainder = " \( remainder) "
170- let fullPaddedRemainder = fullRemainder. leftPadding ( toLength: numberDecimals , withPad: " 0 " )
148+ let fullPaddedRemainder = fullRemainder. leftPadding ( toLength: unitDecimals , withPad: " 0 " )
171149 let remainderPadded = fullPaddedRemainder [ 0 ..< toDecimals]
172150 if remainderPadded == String ( repeating: " 0 " , count: toDecimals) {
173151 if quotient != 0 {
@@ -201,7 +179,7 @@ public struct Utilities {
201179 return fullRemainder + " e- " + String( firstDigit)
202180 }
203181 }
204- if ( toDecimals == 0 ) {
182+ if toDecimals == 0 {
205183 return " \( quotient) "
206184 }
207185 return " \( quotient) " + decimalSeparator + remainderPadded
@@ -309,32 +287,57 @@ public struct Utilities {
309287extension Utilities {
310288 /// Various units used in Ethereum ecosystem
311289 public enum Units {
312- case eth
313290 case wei
314- case Kwei
315- case Mwei
316- case Gwei
317- case Microether
318- case Finney
291+ case kwei
292+ case babbage
293+ case femtoether
294+ case mwei
295+ case lovelace
296+ case picoether
297+ case gwei
298+ case shannon
299+ case nanoether
300+ case nano
301+ case microether
302+ case szabo
303+ case micro
304+ case finney
305+ case milliether
306+ case milli
307+ case ether
308+ case kether
309+ case grand
310+ case mether
311+ case gether
312+ case tether
313+ case custom( Int )
319314
320315 public var decimals : Int {
321- get {
322- switch self {
323- case . eth:
324- return 18
325- case . wei:
326- return 0
327- case . Kwei:
328- return 3
329- case . Mwei:
330- return 6
331- case . Gwei:
332- return 9
333- case . Microether:
334- return 12
335- case . Finney:
336- return 15
337- }
316+ switch self {
317+ case . wei:
318+ return 0
319+ case . kwei, . babbage, . femtoether:
320+ return 3
321+ case . mwei, . lovelace, . picoether:
322+ return 6
323+ case . gwei, . shannon, . nanoether, . nano:
324+ return 9
325+ case . microether, . szabo, . micro:
326+ return 12
327+ case . finney, . milliether, . milli:
328+ return 15
329+ case . ether:
330+ return 18
331+ case . kether, . grand:
332+ return 21
333+ case . mether:
334+ return 24
335+ case . gether:
336+ return 27
337+ case . tether:
338+ return 30
339+ case . custom( let decimals) :
340+ return max ( 0 , decimals)
338341 }
339342 }
340343 }
0 commit comments