
Реализация простых кооперативных потоков на C с использованием setjmp/longjmp и небольшого количества ассемблера.
Оригинал
Перевод на Хабре
Size: a a a
is_sized
, проверяющая является ли тип Sized
, пишется тривиально:fn is_sized<T: ?Sized>() -> bool {
mem::size_of::<*const T>() == mem::size_of::<usize>()
}
String
со датой, отформатированной согласно переданному формату. Выглядит это примерно так (пример из документации):assert_eq!(date!(2019-01-02).format("%Y-%m-%d"), "2019-01-02");Выглядит неплохо, но будем честны: в подавляющем большинстве случаев строка формата так и остаётся литералом. Метод же, тем не менее, вынужден парсить строку при каждом вызове, и лично я сомневаюсь, что этот код будет специализирован на этапе компиляции (всё-таки rustc не является суперкомпилятором). Многократная компиляция регулярных выражений является известным антипаттерном, и для решения этой проблемы есть инструмент, а для формата даты такого инструмента нет. Сегодня мы напишем подобный инструмент сами.
use std::fmt;Сам общий интерфейс форматировщиков:
#[derive(Default)]
pub struct Buf {
inner: String,
}
impl Buf {
pub fn new() -> Self {
Self::default()
}
pub fn append(&mut self, s: &str) {
self.inner += s;
}
// Этот метод позволит нам использовать макрос `write!` на `Buf`.
// Он позволяет не безусловно выделять новую строку,
// а использовать место в уже имеющейся
pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
self.inner.write_fmt(args)
}
}
use std::fmt;(проблем с тем, чтобы принимать
use time::Date;
pub trait FormatDate {
fn format_date(&self, b: &mut Buf, d: Date) -> fmt::Result;
}
Date
по значению, нет, потому что это Copy
-тип).impl FormatDate for &'_ str {Теперь напишем реализацию для, скажем, дня даты:
fn format_date(&self, b: &mut Buf, _: Date) -> fmt::Result {
b.append(self);
Ok(())
}
}
pub struct DayOf;Формат
impl FormatDate for DayOf {
fn format_date(&self, b: &mut Buf, d: Date) -> fmt::Result {
write!(b, "{:02}", d.day())
}
}
"{:02}"
означает, что для печати дня отведено два места, и если в номере дня всего одна цифра, то вывод будет дополнен слева нулями. Форматировщики для номера месяца и года пишутся аналогично, поэтому не будем подробнее на этом останавливаться.Foo
и FooBuilder
, добавьте метод Foo::builder
.