
Rust — подготовленные запросы в PostgreSQL с указанием типа
cargo.toml
[dependencies]
postgres = { version = "0.19.9", features = ["with-uuid-1", "with-chrono-0_4"] }
uuid = { version = "1.11.0", features = ["v4"] }
chrono = "0.4.38"
main.rs
use postgres::{Client, NoTls};
use std::error::Error;
use uuid::Uuid;
use chrono::{NaiveDateTime};
fn main() -> Result<(), Box<dyn Error>> {
let mut conn = Client::connect(
"postgresql://postgres:jopa@localhost:5432/postgres",
NoTls)
.unwrap();
let stuff_id = Uuid::new_v4();
let date_str = "2020-04-12 22:10:57";
let naive_datetime = NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S").unwrap();
conn.execute(
"insert into test (stuff_id, naive_datetime) values ($1, $2)",
&[&stuff_id, &naive_datetime],
)?;
Ok(())
}

Rust — установка через proxy c выводом расширенной информации об установке
Пришлось извращаться с установкой внутри корп. сети с закрытым прямым доступом в Интернет и еще стала выпадать ошибка что на девайсе не достаточно места.
По умолчанию Rust для установки использует домашнюю директорию пользователя, поэтому если видите такую ошибку с местом — увеличьте размер тома.
Далее чтобы произвести установку через прокси нужно к стандартному curl-запросу добавить следующие параметры:
curl -x http://proxy.ru:port --proxy-user 'user:pass' --insecure --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -v -y

Rust — SSH2 sftp download file
use std::net::TcpStream;
use std::io::Read;
use ssh2::Session;
use std::path::Path;
fn main() {
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password("user", "password").unwrap();
let mut contents:Vec<u8> = Vec::new();
let sftp = sess.sftp().unwrap();
let mut stream = sftp.open(Path::new("/tmp/test.txt")).unwrap();
stream.read_to_end(&mut contents).unwrap();
let _ = std::fs::write(r"/tmp/test_out.txt", &contents);
}

Rust — sftp upload file
use std::net::TcpStream;
use std::io::Write;
use std::io::Read;
use std::fs::File;
use ssh2::Session;
use std::path::Path;
fn main() {
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password("user", "pass").unwrap();
let sftp = sess.sftp().unwrap();
let mut local_file = File::open("/tmp/test.txt").expect("no file found");
let mut buffer:Vec<u8> = Vec::new();
let _ :u64 = local_file.read_to_end(&mut buffer).unwrap().try_into().unwrap();
sftp.create(&Path::new("/tmp/file.json"))
.unwrap()
.write_all(&buffer)
.unwrap();
}

Решено! Rust — не собирается под musl — ругаeтся на openssl в Linux.
Если вы решили использовать в своем проекте то, что нужнается в Openssl — будьте готовы что можете столкнуться с кучей ошибок при сборке, особенно если собираете под стандартную реализацию libc в musl.
При сборке cargo вам вывалит что -то подобное:
OPENSSL_DIR unset
cargo:rerun-if-env-changed=OPENSSL_NO_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64-unknown-linux-musl
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64_unknown_linux_musl
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-musl
cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_musl
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-musl
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_musl
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
run pkg_config fail: pkg-config has not been configured to support cross-compilation.
Install a sysroot for the target platform and configure it via
PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_PATH, or install a
cross-compiling wrapper for pkg-config and set it via
PKG_CONFIG environment variable.
--- stderr
thread 'main' panicked at /home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/openssl-sys-0.9.102/build/find_normal.rs:190:5:
Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
compilation process.
Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.
If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.
$HOST = x86_64-unknown-linux-gnu
$TARGET = x86_64-unknown-linux-musl
openssl-sys = 0.9.102
У меня такая фигня пошла, когда я решил добавить Sentry в свой проект.
Решение следующее:
Выполняем команды:
sudo apt-get update
sudo apt-get install -y musl-dev musl-tools linux-headers-$(uname -r)
sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/x86_64-linux-musl/asm && ln -s /usr/include/asm-generic /usr/include/x86_64-linux-musl/asm-generic && ln -s /usr/include/linux /usr/include/x86_64-linux-musl/linux
sudo mkdir /musl
wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1f.tar.gz
tar zxf OpenSSL_1_1_1f.tar.gz
cd openssl-OpenSSL_1_1_1f/
CC="musl-gcc -fPIE -pie -static -idirafter /usr/include/ -idirafter /usr/include/x86_64-linux-gnu/" ./Configure no-shared no-async --prefix=/musl --openssldir=/musl/ssl linux-x86_64
make depend
make -j$(nproc)
sudo make install
Экспортируем переменные окружения:
export PKG_CONFIG_ALLOW_CROSS=1
export OPENSSL_STATIC=true
export OPENSSL_DIR=/musl
Пробуем выполнять сборку:
cargo build --release --target=x86_64-unknown-linux-musl

Rust — увеличить по счетчику значение в HashMap
Я использовал хэш-таблицу в качестве дедубликатора имени ключа. Аналог ассоциативного массива в PHP, когда есть имя ключа и его значение и необходимо добавлять новые значения по имени ключа, при этом нам не нужно каждый раз дублировать эти имена ключей- они должны быть уникальными. Но при этом нам нужно для каждого ключа увеличить его значение, например на +1.
use std::collections::HashMap;
fn main() {
let mut fruits:HashMap<String, i32> = HashMap::new();
fruits.insert(String::from("sds"), 122);
fruits.insert(String::from("qqqq"), 22);
fruits.entry("sds".to_string()).and_modify(|count| *count += 1).or_insert(0);
let first_fruit = fruits.get("sds"); //123
println!("{:?}", first_fruit);}
Пример на Replit тут

RabbitMQ — отправка и чтение очереди через curl
Данный запрос можно делать даже из bash в Linux так как используются стандартные инструменты.
Все необходимое (обменник, очереди) можно создать через WEB-интерфейс RabbitMQ Managment. Предполагаем , что они уже созданы.
Отправляем сообщение в очередь.
В примере ниже :
vhost — имя хоста (exchanges)
delivery_mode 2 — записываем в режиме когда данные очереди сохраняются даже после падения сервера (сохраняются на диск)
routing_key — имя нашей очереди
payload — в данном случае строка , которую мы передаем в сообщении
%2F/amq.default — имя обменника внутри хоста
curl -s -u user:password -H "Accept: application/json" -H "Content-Type:application/json" -X POST -d'{
"vhost": "Test_Virtual_Host",
"properties": {
"delivery_mode": 2,
"headers": {}
},
"routing_key": "testqueues",
"payload":"/dfgdfgfd/dfgdfg/dfgdfgfdg.dat",
"headers": {},
"props": {},
"payload_encoding": "string"
}' http://127.0.0.1:15672/api/exchanges/%2F/amq.default/publish
Читаем сообщение.
curl -s -u user:password -H "content-type:application/json" -X POST -d'{
"count":2,
"ackmode":"ack_requeue_false",
"encoding":"auto",
"truncate":5000
}' http://127.0.0.1:15672/api/queues/%2F/testqueues/get
Удалить обменник через curl.
curl -s -u admin:1234567890 -X DELETE http://127.0.0.1:15672/api/vhosts/Test_Virtual_Host
Rust — вывести тип переменной
pub trait AnyExt {
fn type_name(&self) -> &'static str;
}
impl<T> AnyExt for T {
fn type_name(&self) -> &'static str {
std::any::type_name::<T>()
}
}
fn main(){
let my_number = 32.90;
println!("{}",my_number.type_name());
}
Результат:
f64

Rust — счетчик в ведущими нулями
Задача: вывести счетчик с ведущими нулями, пример 0001, 0002 и т.д.
Задача не сложная, но не стандартная и предполагает несколько вариантов реализации. Мой вариант реализован на том, что мы считаем длину стандартного int счетчика и в зависимости от нее добавляем перед ним нужно количество нулей, которые у нас являются уже строкой.
fn main(){
(1..1002).for_each(|n| {
let _str: String = n.to_string();
let lenght = _str.len();
let mut _zero = String::from("000");
if lenght == 2{
_zero = String::from("00");
}
else if lenght == 3{
_zero = String::from("0");
}
else if lenght == 4{
_zero = String::from("");
}
println!("{}{}",_zero, n);
});
}
Реализация этого же через match:
fn main(){
(1..1002).for_each(|n| {
let _str: String = n.to_string();
let lenght = _str.len();
match lenght {
2 => {println!("00{}", n);}
3 => {println!("0{}", n);}
4 => {println!("{}", n);}
_ => {println!("000{}", n);}
}
});
}