(c *Context, s string)
| 103 | } |
| 104 | |
| 105 | func (d *Decimal) setString(c *Context, s string) (Condition, error) { |
| 106 | orig := s |
| 107 | s, d.Negative = consumePrefix(s, "-") |
| 108 | if !d.Negative { |
| 109 | s, _ = consumePrefix(s, "+") |
| 110 | } |
| 111 | s = strings.ToLower(s) |
| 112 | d.Exponent = 0 |
| 113 | d.Coeff.SetInt64(0) |
| 114 | // Until there are no parse errors, leave as NaN. |
| 115 | d.Form = NaN |
| 116 | if strings.HasPrefix(s, "-") || strings.HasPrefix(s, "+") { |
| 117 | return 0, fmt.Errorf("could not parse: %s", orig) |
| 118 | } |
| 119 | switch s { |
| 120 | case "infinity", "inf": |
| 121 | d.Form = Infinite |
| 122 | return 0, nil |
| 123 | } |
| 124 | isNaN := false |
| 125 | s, consumed := consumePrefix(s, "nan") |
| 126 | if consumed { |
| 127 | isNaN = true |
| 128 | } |
| 129 | s, consumed = consumePrefix(s, "snan") |
| 130 | if consumed { |
| 131 | isNaN = true |
| 132 | d.Form = NaNSignaling |
| 133 | } |
| 134 | if isNaN { |
| 135 | if s != "" { |
| 136 | // We ignore these digits, but must verify them. |
| 137 | _, err := strconv.ParseUint(s, 10, 64) |
| 138 | if err != nil { |
| 139 | return 0, fmt.Errorf("parse payload: %s: %w", s, err) |
| 140 | } |
| 141 | } |
| 142 | return 0, nil |
| 143 | } |
| 144 | |
| 145 | exps := make([]int64, 0, 2) |
| 146 | if i := strings.IndexByte(s, 'e'); i >= 0 { |
| 147 | exp, err := strconv.ParseInt(s[i+1:], 10, 32) |
| 148 | if err != nil { |
| 149 | return 0, fmt.Errorf("parse exponent: %s: %w", s[i+1:], err) |
| 150 | } |
| 151 | exps = append(exps, exp) |
| 152 | s = s[:i] |
| 153 | } |
| 154 | if i := strings.IndexByte(s, '.'); i >= 0 { |
| 155 | exp := int64(len(s) - i - 1) |
| 156 | exps = append(exps, -exp) |
| 157 | s = s[:i] + s[i+1:] |
| 158 | } |
| 159 | for _, ch := range s { |
| 160 | if ch < '0' || ch > '9' { |
| 161 | return 0, fmt.Errorf("parse mantissa: %s", s) |
| 162 | } |
no test coverage detected