Assuming by your example that the type is known at comptime, you can switch based on @typeInfo.
pub fn deinit(comptime T: type, rc_ptr: RcPtr(T), allocator: std.mem.Allocator) void {
// do whatever other logic...
switch (@typeInfo(T).Pointer.size) {
.One => allocator.destroy(value_ptr),
.Many => allocator.free(value_ptr),
else => unreachable, // .Slice, .C
}
}