in starlark/src/stdlib/funcs.rs [515:597]
fn int(ref a: Option<Value>, base: Option<Value>) -> anyhow::Result<i32> {
if a.is_none() {
return Ok(0);
}
let a = a.unwrap();
if let Some(s) = a.unpack_str() {
let base = match base {
Some(base) => base.to_int()?,
None => 0,
};
if base == 1 || base < 0 || base > 36 {
return Err(anyhow!(
"{} is not a valid base, int() base must be >= 2 and <= 36",
base
));
}
let (sign, s) = {
match s.chars().next() {
Some('+') => (1, s.get(1..).unwrap()),
Some('-') => (-1, s.get(1..).unwrap()),
_ => (1, s),
}
};
let base = if base == 0 {
match s.get(0..2) {
Some("0b") | Some("0B") => 2,
Some("0o") | Some("0O") => 8,
Some("0x") | Some("0X") => 16,
_ => 10,
}
} else {
base as u32
};
let s = match base {
16 => {
if s.starts_with("0x") || s.starts_with("0X") {
s.get(2..).unwrap()
} else {
s
}
}
8 => {
if s.starts_with("0o") || s.starts_with("0O") {
s.get(2..).unwrap()
} else {
s
}
}
2 => {
if s.starts_with("0b") || s.starts_with("0B") {
s.get(2..).unwrap()
} else {
s
}
}
_ => s,
};
match i32::from_str_radix(s, base) {
Ok(i) => Ok(sign * i),
Err(x) => Err(anyhow!(
"{} is not a valid number in base {}: {}",
a.to_repr(),
base,
x,
)),
}
} else if let Some(base) = base {
Err(anyhow!(
"int() cannot convert non-string with explicit base '{}'",
base.to_repr()
))
} else if let Some(Num::Float(f)) = a.unpack_num() {
match Num::from(f.trunc()).as_int() {
Some(i) => Ok(i),
None => Err(anyhow!(
"int() cannot convert float to integer: {}",
a.to_repr()
)),
}
} else {
Ok(a.to_int()?)
}
}