#prog #rust #rustlib
pretty-hex
Библиотека для отладочной печати бинарных данных в шестнадцатиричном виде. Поддерживает однострочный вывод и многоколоночный с настраиваемой шириной и переводом в буквы значений, являющихся ASCII-кодами.
pretty-hex
Библиотека для отладочной печати бинарных данных в шестнадцатиричном виде. Поддерживает однострочный вывод и многоколоночный с настраиваемой шириной и переводом в буквы значений, являющихся ASCII-кодами.
use pretty_hex::*;Output:
let cfg = HexConfig {
title: false,
width: 8,
group: 0,
..HexConfig::default()
};
let v = &include_bytes!("data");
assert_eq!(
config_hex(&v, cfg),
format!("{:?}", v.hex_conf(cfg)),
);
println!("{:?}", v.hex_conf(cfg));
0000: 6b 4e 1a c3 af 03 d2 1e kN......(thanks @goldsteinq)
0008: 7e 73 ba c8 bd 84 0f 83 ~s......
0010: 89 d5 cf 90 23 67 4b 48 ....#gKH
0018: db b1 bc 35 bf ee ...5..
Lib.rs
pretty-hex — for debugging in Rust
Pretty hex dump of bytes slice in the common style
👍9🔥4💔1
Forwarded from dev optozorax
Завтра будет частичное солнечное затмение.
Зайдите сюда: https://www.timeanddate.com/eclipse/map/2022-october-25, впишите свой город в поиск на карте, и смотрите когда оно будет в полной фазе по вашему локальному времени, пример [Москва].
Лучший способ увидеть затмение - через тени маленьких объектов, по типу листьев, все их тени будут в форме полумесяца. Увидеть затмение на солнце будет сложно или легко в зависимости от вашей локации. Лучше заранее найти что-то по типу маски для сварки.
А узнать через сколько лет будет следующее затмение можно в моём репозитории: https://github.com/optozorax/sun-eclipses#частное-солнечное-затмение-25-октября-2022-г
Зайдите сюда: https://www.timeanddate.com/eclipse/map/2022-october-25, впишите свой город в поиск на карте, и смотрите когда оно будет в полной фазе по вашему локальному времени, пример [Москва].
Лучший способ увидеть затмение - через тени маленьких объектов, по типу листьев, все их тени будут в форме полумесяца. Увидеть затмение на солнце будет сложно или легко в зависимости от вашей локации. Лучше заранее найти что-то по типу маски для сварки.
А узнать через сколько лет будет следующее затмение можно в моём репозитории: https://github.com/optozorax/sun-eclipses#частное-солнечное-затмение-25-октября-2022-г
Timeanddate
Partial Solar Eclipse on 25 Oct 2022: Path Map & Times
Interactive map showing where the partial solar eclipse of 25 Oct 2022 is visible—with local times and average cloud cover for any location.
❤1💔1
#prog #rust #rustasync #article
An Unfortunate Experience with Rust
I consider myself to be pretty experienced in Rust. I’ve been using Rust in personal projects since late 2016 and professionally since early 2021. I’ve prepared internal presentations to teach coworkers about borrow checking and about async programming. However, even I still occasionally run into issues fighting the Rust compiler, and the following is a series of particularly unfortunate issues I ran into at work this week.
An Unfortunate Experience with Rust
I consider myself to be pretty experienced in Rust. I’ve been using Rust in personal projects since late 2016 and professionally since early 2021. I’ve prepared internal presentations to teach coworkers about borrow checking and about async programming. However, even I still occasionally run into issues fighting the Rust compiler, and the following is a series of particularly unfortunate issues I ran into at work this week.
Considerations on Codecrafting
An Unfortunate Experience with Rust
Programming, math, and other things gratuitously nerdy
💔1
Forwarded from Подлый апельсинчик
YouTube
Interview with Senior JS Developer
👔 Merch drop 2023: https://posix.store
Javascript programming language
Interview with a Javascript developer with Jack Borrough - aired on © The Javascript.
Find more Javascript opinions under:
https://hackernoon.com/how-it-feels-to-learn-javascript-in…
Javascript programming language
Interview with a Javascript developer with Jack Borrough - aired on © The Javascript.
Find more Javascript opinions under:
https://hackernoon.com/how-it-feels-to-learn-javascript-in…
👍2😁1💔1
#prog #rust #моё
Допустим, есть трейт, в интерфейсе которого желательно иметь опциональный метод для оптимизации. Чтобы разговор был более предметным, покажу конкретный пример для иллюстрации излагаемого далее:
===
Первый способ: добавить метод с реализацией по умолчанию, которая ничего не делает:
===
Второй способ: дополнительный трейт и специализация:
Допустим, есть трейт, в интерфейсе которого желательно иметь опциональный метод для оптимизации. Чтобы разговор был более предметным, покажу конкретный пример для иллюстрации излагаемого далее:
trait Push<T> {
fn push_single(&mut self, x: T);
}
impl<T> Push<T> for Vec<T> {
fn push_single(&mut self, x: T) {
self.push(x);
}
}
use std::sync::mpsc::Sender;
impl<T> Push<T> for Sender<T> {
fn push_single(&mut self, x: T) {
self.send(x).unwrap();
}
}
Некоторые из типов, которые реализуют Push
, могут зарезервировать память под n
следующих элементов (Vec<T>
), но не все (Sender<T>
). Хотелось бы иметь метод reserve_for_push
для этого, но как его интегрировать?===
Первый способ: добавить метод с реализацией по умолчанию, которая ничего не делает:
trait Push<T> {
fn push_single(&mut self, x: T);
fn reserve_for_push(&mut self, n: usize) {}
}
impl<T> Push<T> for Vec<T> {
// ...
fn reserve_for_push(&mut self, n: usize) {
self.reserve(n);
}
}
// реализация для `Sender<T>` без изменений
Это простой и рабочий метод. Его использование выглядит так:fn push_vec<T, P: Push<T>>(p: &mut P, xs: Vec<T>) {С одной стороны, это изменение обратно-совместимо. С другой стороны, так как оно обратно-совместимо, существующие реализации, скорее всего, не будут обновлены для того, чтобы переопределить реализацию по умолчанию (я смотрю на тебя, Clone::clone_from). Также вызывающая сторона не может выяснить, поддерживает ли тип этот метод или нет.
p.reserve_for_push(xs.len());
for x in xs {
p.push_single(x);
}
}
===
Второй способ: дополнительный трейт и специализация:
trait Push<T> { ... }
trait ReserveForPush<T>: Push<T> {
fn reserve_for_push(&mut self, n: usize);
}
impl<T> ReserveForPush<T> for Vec<T> {
fn reserve_for_push(&mut self, n: usize) {
self.reserve(n);
}
}
// остальной код тот же
Вызывающая сторона, которая желает воспользоваться возможной оптимизацией, может сделать это явно через введение трейта, который является точкой специализации:#![feature(specialization)] // <-- с min_specialization не работает
...
trait ReserveForPushSpec<T>: Push<T> {
fn maybe_reserve(&mut self, n: usize);
}
impl<T, P> ReserveForPushSpec<T> for P
where
P: Push<T>,
{
// неспециализированная реализация
default fn maybe_reserve(&mut self, n: usize) {}
}
impl<T, P> ReserveForPushSpec<T> for P
where
P: ReserveForPush<T>,
{
fn maybe_reserve(&mut self, n: usize) {
self.reserve_for_push(n);
}
}
Теперь вызывающая сторона может либо требовать ReserveForPush
и вызывать reserve_for_push
для гарантированного наличия метода, либо ReserveForPushSpec
и вызывать maybe_reserve
для негарантированного наличия оптимизированного метода, но при этом автоматического его использования при его наличии:fn push_vec<T, P>(p: &mut P, xs: Vec<T>)Разумеется, из-за специализации это сейчас работает лишь на nightly. С другой стороны, это изменение обратно-совместимо.
where
P: ReserveForPushSpec<T>,
{
p.maybe_reserve(xs.len());
for x in xs {
p.push_single(x);
}
}
fn push_vec_super_duper_fast<T, P>(p: &mut P, xs: Vec<T>)
where
P: ReserveForPush<T>,
{
p.reserve_for_push(xs.len());
for x in xs {
p.push_single(x);
}
}
doc.rust-lang.org
Clone in std::clone - Rust
A common trait for the ability to explicitly duplicate an object.
❤4👍1👎1💔1
Третий способ: вынос метода как значения.
Мы не можем сделать опциональный метод как таковой, но мы можем сделать ассоциированную константу типа
===
Rust всё ещё очень слаб с обращением с константами на уровне сигнатур. Но он работает с проверками на уровне типов! Так что возможен также и
Четвёртый способ
, а именно — вынос
Для начала определим сам type-level Option:
Из недостатков:
* ломает обратную совместимость
* трейт не object-safe
* для общего случая нужно импортировать трейт ради метода
Не как всегда, в этот раз без гиста.
Мы не можем сделать опциональный метод как таковой, но мы можем сделать ассоциированную константу типа
Option
— в частности, оборачивающий тип метода на Self
:type ReserveForPush<P> = fn(&mut P, usize);Вызывающий код теперь может проверять в рантайме наличие метода и вызывать его:
trait Push<T> {
fn push_single(&mut self, x: T);
const RESERVE_FOR_PUSH: Option<ReserveForPush<Self>>;
}
impl<T> Push<T> for Vec<T> {
fn push_single(&mut self, x: T) {
self.push(x);
}
const RESERVE_FOR_PUSH: Option<ReserveForPush<Self>> =
Some(Self::reserve);
}
impl<T> Push<T> for Sender<T> {
fn push_single(&mut self, x: T) {
self.send(x).unwrap();
}
const RESERVE_FOR_PUSH: Option<ReserveForPush<Self>> = None;
}
fn push_vec<T, P>(p: &mut P, xs: Vec<T>)
where
P: Push<T>,
{
if let Some(f) = P::RESERVE_FOR_PUSH {
f(p, xs.len());
}
for x in xs {
p.push_single(x);
}
}
Из недостатков: не обратно-совместимо, нельзя статически требовать наличия метода, трейт теперь не object-safe.===
Rust всё ещё очень слаб с обращением с константами на уровне сигнатур. Но он работает с проверками на уровне типов! Так что возможен также и
Четвёртый способ
, а именно — вынос
Option
на уровень типов.Для начала определим сам type-level Option:
mod ty_opt {
// Rust не поддерживает перечисления на уровне типов,
// поэтому сделаем две альтернативы и объединим их
// через sealed trait
mod private {
pub trait Sealed {}
impl<T> Sealed for super::Some<T> {}
impl Sealed for super::None {}
}
pub struct Some<T>(pub T);
pub struct None;
pub trait TypeOption<T>: private::Sealed {
// нам нужно как-то в итоге заматчиться
// по значению, поэтому предоставим
// метод для унификации
fn unlift(self) -> Option<T>;
}
impl<T> TypeOption<T> for Some<T> {
fn unlift(self) -> Option<T> {
::core::option::Option::Some(self.0)
}
}
impl<T> TypeOption<T> for None {
fn unlift(self) -> Option<T> {
::core::option::Option::None
}
}
}
Теперь внесём этот type-level Option в интерфейс Push
:type ReserveForPush<P> = fn(&mut P, usize);
trait Push<T> {
fn push_single(&mut self, x: T);
type ReserveForPushOpt: ty_opt::TypeOption<ReserveForPush<Self>>;
const RESERVE_FOR_PUSH_OPT: Self::ReserveForPushOpt;
}
И реализуем Push<T>
для всё тех же типов:impl<T> Push<T> for Vec<T> {
fn push_single(&mut self, x: T) {
self.push(x);
}
type ReserveForPushOpt = ty_opt::Some<ReserveForPush<Self>>;
const RESERVE_FOR_PUSH_OPT: Self::ReserveForPushOpt
= ty_opt::Some(Self::reserve);
}
impl<T> Push<T> for Sender<T> {
fn push_single(&mut self, x: T) {
self.send(x).unwrap();
}
type ReserveForPushOpt = ty_opt::None;
const RESERVE_FOR_PUSH_OPT: Self::ReserveForPushOpt
= ty_opt::None;
}
Теперь мы можем сделать общую функцию, которая по возможности использует этот опциональный метод:use ty_opt::TypeOption;
fn push_vec<T, P>(p: &mut P, xs: Vec<T>)
where
P: Push<T>,
{
if let Some(f) = P::RESERVE_FOR_PUSH_OPT.unlift() {
f(p, xs.len());
}
for x in xs {
p.push_single(x);
}
}
И у нас всё ещё есть возможность требовать наличие метода статически:use ty_opt::TypeOption;
fn push_vec_super_duper_fast<T, P>(p: &mut P, xs: Vec<T>)
where
P: Push<T, ReserveForPushOpt = ty_opt::Some<ReserveForPush<P>>>,
{
let ty_opt::Some(f) = P::RESERVE_FOR_PUSH_OPT;
f(p, xs.len());
for x in xs {
p.push_single(x);
}
}
При желании можно даже гарантировать отсутствие метода, но мне сложно представить ситуацию, когда это было бы нужно.Из недостатков:
* ломает обратную совместимость
* трейт не object-safe
* для общего случая нужно импортировать трейт ради метода
unlift
* боже зачем вам этоНе как всегда, в этот раз без гиста.
Telegram
Блог*
#prog #rust #моё #article
Здрасьте. Сегодня поста не будет — но только потому, что я решил написать статью для Хабра. Собственно, вот она.
И напоминаю: если вам это понравилось — поддержите копеечкой автора, я вам благодарен буду: 4274 3200 5402 8520.
Здрасьте. Сегодня поста не будет — но только потому, что я решил написать статью для Хабра. Собственно, вот она.
И напоминаю: если вам это понравилось — поддержите копеечкой автора, я вам благодарен буду: 4274 3200 5402 8520.
👍7🤯1💔1
Forwarded from Протестировал (Sergey Bronnikov)
Помните SETI@home? Проект анализировал радиосигнал из космоса для поиска внеземного разума используя для этого вычислительные ресурсы добровольцев. По аналогии с SETI@Home есть проект Fuzzing@Home, в котором можно запускать фаззинг проектов, добавленных в OSS Fuzz, в обычном веб браузере. Это возможно благодаря компиляции в WebAssembly. Попробуйте сами - https://fuzzcoin.gtisc.gatech.edu:8000/
👍5💔1
DELO (18+)
17 октября 2022 года состоялись общественные слушания по принятию законопроекта, полностью запрещающего "пропаганду" ЛГБТ+. На следующую неделю запланировано первое чтение. Депутаты Госдумы высказались, что ЛГБТ – оружие Запада, угрожающее государственной…
Госдума единогласно приняла в I чтении пакет законопроектов о запрете «пропаганды нетрадиционных сексуальных отношений».
ЕДИНОГЛАСНО, БЛЯТЬ. Какие же конченые мрази.
ЕДИНОГЛАСНО, БЛЯТЬ. Какие же конченые мрази.
🤬10💔5💩3😁1